package cn.com.collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * @author water * @version 创建时间:2016年9月12日 下午4:02:42 * 类说明 */ public class TestMap { public static void main(String[] args) { // TODO Auto-generated method stub Map map = new HashMap(1000); for(int i=0;i<1000;i++){ map.put(i+"", "str"+i); } // 方法一、推荐只用value的时候用 // Map.values()遍历所有的value,不遍历key for (Object v : map.values()) { System.out.println("value= " + v); } //推荐只用keys的时候用 for(Object key : map.keySet()){ System.out.println("key= "+ key ); } //方法二:取二次值,先取key再取value,建议只需要用key的时候使用,节省时间、空间 for(Object key : map.keySet()){ System.out.println("key= "+ key + " and value= " + map.get(key)); } //方法三:取一次值,一次把key和value全部取出 //entrySet使用iterator遍历key和value Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 四、推荐,尤其是容量大时,TreeMap尤其推荐 // entrySet遍历key和value for (Object obj : map.entrySet()) { Map.Entry entry = (Map.Entry) obj; System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } } }
比较keySet和EntrySet性能
package cn.com.collection; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; /** * @author gaohuashui * @version 创建时间:2016年9月12日 下午4:20:18 类说明 */ public class TestMap2 { public static void main(String[] args) { Map map = new HashMap(1000000); //Map map = new TreeMap(); for (int i = 0; i < 1000000; i++) { map.put(i + "", "str" + i); } // 二次取值 long current = System.currentTimeMillis(); for (Object key : map.keySet()) { map.get(key); } System.out.println("keySet cost time : "+String.valueOf(System.currentTimeMillis() - current)); // entrySet遍历key和value long current1 = System.currentTimeMillis(); for (Object obj : map.entrySet()) { Map.Entry entry = (Map.Entry) obj; entry.getKey(); entry.getValue(); } System.out.println("entrySet cost time : "+String.valueOf(System.currentTimeMillis() - current1)); } }执行以上代码,结果:
keySet cost time : 52
entrySet cost time : 33
由结果我们发现,entrySet 的效率高于keySet。同时遍历key和value时,keySet与entrySet方法的性能差异取决于key的具体情况,如复杂度(复杂对象)、离散度、冲突率等。换言之,取决于HashMap查找value的开销。entrySet一次性取出所有key和value的操作是有性能开销的,当这个损失小于HashMap查找value的开销时,entrySet的性能优势就会体现出来。当key是最简单的数值字符串时,keySet可能反而会更高效,在我的例子中没有测出,总体来说还是推荐使用entrySet。因为当key很简单时,其性能或许会略低于keySet,但却是可控的;而随着key的复杂化,entrySet的优势将会明显体现出来。当然,我们可以根据实际情况进行选择。
当我们将HashMap换成TreeMap时,我们发现EntrySet的效率大大地高出了KeySet。这是由TreeMap的查询效率决定的,也就是说,TreeMap查找value的开销较大,明显高于entrySet一次性取出所有key和value的开销。因此,遍历TreeMap时强烈推荐使用entrySet方法。
当然在使用过程中,如果只需要key时,我们选择keySet,如果只使用Value时,我们使用Values取出值即可。