java 高效的hashmap遍历方法


Hashmap的遍历,key和value通常的方法有两种,及使用entryset或者keyset遍历,下面我们来看下实例。

public class TestHashMap {	

private static void test1(){//效率低
Map<String,String> map = new HashMap<String,String>();
long time1 = System.currentTimeMillis(); 
for (int i = 0; i < 100000; i++) {
map.put("two"+i, 2+"");  
map.put("three"+i, 3+"");  
map.put("four"+i, 4+"");  
map.put("five"+i, 5+"");  
}

for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {
String s = iterator.next();
String m = map.get(s);
}
long time2 = System.currentTimeMillis();
long time = time2-time1;
System.out.println(time);
}




private static void test2(){//效率高
Map<String,String> map = new HashMap<String,String>();
long time1 = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
map.put("two"+i, 2+"");  
map.put("three"+i, 3+"");  
map.put("four"+i, 4+"");  
map.put("five"+i, 5+"");  
}
for (Iterator<Entry<String, String>> iterator = map.entrySet().iterator(); iterator.hasNext();) {
Entry<String, String> s = iterator.next();
String m = s.getValue();
String n = s.getKey();
}
long time2 = System.currentTimeMillis();
long time = time2-time1;
System.out.println(time);
}


public static void main(String[] args){
test1();
test2();
}

}

Hashmap是一个通过散列表实现的存储,底层是数组存放的元素,而hashmap的一个元素就是一个entry,也就是一个key-value的键值对,所以通过entry的遍历可以一次获取到key-value的键值对。但是通过keyset遍历的话,是先set集合里取出key,然后再通过map.get(key)活得value,通过hashmap源码分析得知,get(key)方法是又进行了一次迭代,找到entry,从而获得到的value,所以效率上用entry遍历更高。下面来看下map的get源码:


public V get(Object key) {
        if (key == null) {
            HashMapEntry<K, V> e = entryForNullKey;
            return e == null ? null : e.value;
        }


        // Doug Lea's supplemental secondaryHash function (inlined)
        int hash = key.hashCode();
        hash ^= (hash >>> 20) ^ (hash >>> 12);
        hash ^= (hash >>> 7) ^ (hash >>> 4);


        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {
                return e.value;
            }

        }
        return null;
    }

通过源码分析得知,当通过 key 取出对应 value 时,系统只要先计算出该 key 的 hashCode() 返回值,在根据该 hashCode 返回值找出该 key 在 table 数组中的索引,取出该索引处的 Entry,最后返回该 key 对应的 value 即可,此时如果对应的索引只存取一个entry,效率最高,但是如果hash冲突导致,存储的是一个entry链,就需要遍历找到需要的entry,这时候效率就要下降了。

但是大家有没有发现hashmap遍历是无序的呢,我们会在接下来的文章给大家讲解,谢谢。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java中,遍历HashMap有两种常见的方式:使用entrySet()方法遍历和使用keySet()方法遍历。这两种方式各有优劣,具体哪种更好取决于你的需求和场景。 1. 使用entrySet()方法遍历: 这种方式通过获取键值对(Entry)的集合来遍历HashMap。优点是可以同时获得键和值,适用于需要同时操作键和值的场景。例如: ```java HashMap<String, Integer> map = new HashMap<>(); // 添加键值对 map.put("A", 1); map.put("B", 2); map.put("C", 3); // 使用entrySet()方法遍历 for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); // 进行操作 } ``` 缺点是相比于使用keySet()方法遍历会稍微慢一些,因为需要额外获取每个键值对的引用。 2. 使用keySet()方法遍历: 这种方式通过获取键的集合来遍历HashMap。优点是速度相对较快,适用于只需要操作键的场景。例如: ```java HashMap<String, Integer> map = new HashMap<>(); // 添加键值对 map.put("A", 1); map.put("B", 2); map.put("C", 3); // 使用keySet()方法遍历 for (String key : map.keySet()) { Integer value = map.get(key); // 进行操作 } ``` 缺点是如果需要同时操作键和值,则需要通过键再次获取值,相对于使用entrySet()方法遍历会多一次获取值的操作。 总之,如果你需要同时操作键和值,则使用entrySet()方法遍历更合适;如果只需要操作键,则使用keySet()方法遍历高效。根据具体的需求选择适合的方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值