• Java数据结构之Map学习总结


    前言:

        前面学习总结了List的使用及效率对比,今天总结学习一下键值映射关系Map,顺便学习一下Android中使用Map需要注意哪些,以及谷歌官方针对Android对Map做了哪些优化。

    先了解下Map

       Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。 Map没有继承于Collection接口 从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。 

    Map是一个接口,实例化Map可以采用下面的方式:

    • HashMap //Map基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能。 
    • LinkedHashMap  //类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点。而在迭代访问时发而更快,因为它使用链表维护内部次序。 
    • TreeMap //底层是二叉树数据结构,线程不同步,可用于给Map集合中的键进行排序。
    • HashTable //HashMap是Hashtable的轻量级实现,非线程安全的实现他们都实现了map接口,主要区别是HashMap键值可以为空null,效率可以高于Hashtable。
    • ConcurrentHashMap //ConcurrentHashMap通常只被看做并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap。
    • WeakHashMap //弱键(weak key)Map,Map中使用的对象也被允许释放: 这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收。
    • IdentifyHashMap //使用==代替equals()对“键”作比较的hash map
    • ArrayMap //ArrayMap是一个<key,value>映射的数据结构,它设计上更多的是考虑内存的优化,内部是使用两个数组进行数据存储,一个数组记录key的hash值,另外一个数组记录Value值,它和SparseArray一样,也会对key使用二分法进行从小到大排序,在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index,然后通过index来进行添加、查找、删除等操作,所以,应用场景和SparseArray的一样,如果在数据量比较大的情况下,那么它的性能将退化至少50%。
    • SparseArray //SparseArray比HashMap更省内存,在某些条件下性能更好,主要是因为它避免了对key的自动装箱(int转为Integer类型),它内部则是通过两个数组来进行数据存储的,一个存储key,另外一个存储value,为了优化性能,它内部对数据还采取了压缩的方式来表示稀疏数组的数据,从而节约内存空间。

    Map的基本操作:

    • Object put(Object key, Object value): 向集合中加入元素   
    • Object remove(Object key): 删除与KEY相关的元素   
    • void putAll(Map t):  将来自特定映像的所有元素添加给该映像   
    • void clear():从映像中删除所有映射   

    Map使用

      这里以最常用的HashMap为例

     添加数据

       Map<Integer, String> hashMap = new HashMap<>();
       for (int i = 0; i < maxCount; i++) {
          hashMap.put(i, String.valueOf(i));
       }

    遍历entrySet方式

    复制代码
     long start = System.currentTimeMillis();
     for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
            Integer key=entry.getKey();
            String  value=entry.getValue();
            Log.i(TAG, "key: " + key +"value: "+value);
         }
    
        long end = System.currentTimeMillis();
        Log.e(TAG, "for-each方式 cost time : " + (end - start));
    复制代码

    entrySet迭代器遍历方式

    复制代码
    long start1 = System.currentTimeMillis();
    Iterator<Map.Entry<Integer, String>> entries = hashMap.entrySet().iterator();
    
    while (entries.hasNext()) {
        Map.Entry<Integer, String> entry = entries.next();
        Integer key=entry.getKey();
        String  value=entry.getValue();
        Log.i(TAG, "key: " + key +"value: "+value);
       }
    
    long end1 = System.currentTimeMillis();
    Log.e(TAG, "entrySet iterator迭代器 cost time : " + (end1 - start1));
    复制代码

    键找值遍历

    复制代码
     long end1 = System.currentTimeMillis();
     Log.e(TAG, "iterator迭代器 cost time : " + (end1 - start1));
    
     long start2 = System.currentTimeMillis();
     for (Integer key : hashMap.keySet()) {
          String value = hashMap.get(key);
          Log.i(TAG, "key: " + key +"value: "+value);
     }
    
      long end2 = System.currentTimeMillis();
      Log.e(TAG, "键找值遍历 cost time : " + (end2 - start2));
    复制代码

    keySet迭代器遍历

    复制代码
    long start3 = System.currentTimeMillis();
    
    Iterator<Integer> iterator=hashMap.keySet().iterator();
            while (iterator.hasNext()) {
            Integer key=iterator.next();
            String  value=hashMap.get(key);
            Log.i(TAG, "key: " + key +"value: "+value);
        }
    
     long end3 = System.currentTimeMillis();
     Log.e(TAG, "keySet iterator迭代器 cost time : " + (end3 - start3));
    复制代码

     上述四种情况执行结果如下:

    总结:

      主要重新熟悉一下Map这种数据结构,以及更好的在以后的编程中选择更合适的方式来进行key-value存储。

  • 相关阅读:
    Linux常用命令3
    清空指定表的所有记录数据。
    向已经创建好的表添加和删除指定的列族或列。
    在终端打印出指定表的所有记录数据。
    列出HBASE所有表的相关信息,如表名、创建时间等。
    我在校园自动签到系统
    charles配置
    计算机网络第7版 PDF+ 计算机网络释疑与习题解答第7版 PDF 计算机网络 课后答案
    在HDFS中将文件从源路径移动到目的路径。
    删除HDFS中指定的文件。
  • 原文地址:https://www.cnblogs.com/wuyuxin/p/6993987.html
Copyright © 2020-2023  润新知