• HashMap两种遍历数据的方式


    HashMap的遍历有两种方式,一种是entrySet的方式,另外一种是keySet的方式。

    第一种利用entrySet的方式:

    Map map = new HashMap();
    Iterator iter = map.entrySet().iterator();
    while (iter.hasNext()) {
    Map.Entry entry = (Map.Entry) iter.next();
       Object key = entry.getKey();
       Object val = entry.getValue();
    }

    上面的方式可以变化为for循环的形式:

    Map<String, String> map = new HashMap<String, String>();
    for (Entry<String, String> entry : map.entrySet()) {
        entry.getKey();
        entry.getValue();
    }

    第二种利用keySet的方式:

    Map map = new HashMap();
    Iterator iter = map.keySet().iterator();
    while (iter.hasNext()) {
        Object key = iter.next();
        Object val = map.get(key);
    }

    上面的方式也可以变化为for循环的形式:

    Map<String, String> map = new HashMap<String, String>();
    for (String key : map.keySet()) {
        map.get(key);
    }

    这两种方式那种效率高呢?可以从下面的试验可以看出来:

    public class Test
    {
        public static void main(String[] args)
        {
            HashMap<String, String> map = new HashMap<String, String>();
            for (int i = 0; i < 1000000; i++)
            {
                map.put(i + "", "hello world");
            }
            long begin1 = System.currentTimeMillis();
            Iterator iterator1 = map.entrySet().iterator();
            while (iterator1.hasNext())
            {
                Map.Entry entry = (Map.Entry) iterator1.next();
                Object key1 = entry.getKey();
                Object val1 = entry.getValue();
            }
            long end1 = System.currentTimeMillis();
            System.out.println("map.entrySet方式变量花费的时间为:" + (end1 - begin1));
            long begin2 = System.currentTimeMillis();
            Iterator iterator2 = map.keySet().iterator();
            while (iterator2.hasNext())
            {
                Object key2 = iterator2.next();
                Object val2 = map.get(key2);
            }
            long end2 = System.currentTimeMillis();
            System.out.println("map.keySet方式变量花费的时间为:" + (end2 - begin2));
        }
    }

    结论:
    经过运行多次,我发现两者的运行时间相差不多,而且没有明确显示出那种变量方式更快一些。有的人可能会觉得第一种变量方式会快一些,因为他们觉 得:keySet方式其实是遍历了2次,一次是转为iterator,一次就从HashMap中取出key所对应的value,而entry方式只遍历了 一次,把key和value都放到了entry中,所以entry方式更快一些。
    但是我觉得这种分析的方式比较主观,我们更应该从源码的角度去分析。首先看一下迭代器的源码:

    keySet的迭代器:

    private final class KeyIterator extends HashIterator<K> {
        public K next() {
            return nextEntry().getKey();
        }
    }

    entrySet的迭代器:

    private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
        public Map.Entry<K,V> next() {
            return nextEntry();
        }
    }

    从上面我们可以看到只是返回值不同而已,父类相同,所以性能相差不多。下面我们再看一下get方法的源码:

    public V get(Object key) {
    if (key == null)
    return getForNullKey();
    Entry<K,V> entry = getEntry(key);
    return null == entry ? null : entry.getValue();
    }
    final Entry<K,V> getEntry(Object key) {
    int hash = (key == null) ? 0 : hash(key);
    for (Entry<K,V> e = table[indexFor(hash, table.length)];
    e != null;
    e = e.next) {
    Object k;
    if (e.hash == hash &&
    ((k = e.key) == key || (key != null && key.equals(k))))
    return e;
    }
    return null;
    }

    从上面的源码发现get的时间复杂度取决于for循环循环次数,即hash算法。所以两种性能差别不大。从上面的分析来看,我们得到最终的结论:
    (1)HashMap的循环,如果既需要key也需要value,直接用下面的即可,foreach简洁易懂。

    Map<String, String> map = new HashMap<String, String>();
    for (Entry<String, String> entry : map.entrySet()) {
        entry.getKey();
        entry.getValue();
    }

    (2)如果只是遍历key而无需value的话,可以直接用下面的方式:

    Map<String, String> map = new HashMap<String, String>();
    for (String key : map.keySet()) {
        // key process
    }

    原文地址:http://swiftlet.net/archives/1259

  • 相关阅读:
    【linux磁盘与文件系统管理】8-RAID工作原理和实现
    【linux磁盘与文件系统管理】5,6,7-文件系统使用-管理
    【linux磁盘与文件系统管理】3,4-MBR和GPT分区-分区管理
    【linux磁盘与文件系统管理】2-分区表MBR
    【linux磁盘与文件系统管理】1-磁盘结构和概念
    01学习Vue.js过程总结
    oracle表管理(建表,改表,删表,表数据增删改查)
    oracle数据类型
    Orcal登录密码过期
    基于Container部署的k8s集群
  • 原文地址:https://www.cnblogs.com/longshiyVip/p/4633190.html
Copyright © 2020-2023  润新知