美文网首页一些收藏
[Java]重学Java-Map

[Java]重学Java-Map

作者: AbstractCulture | 来源:发表于2022-04-13 10:34 被阅读0次

    HashMap

    关于HashMap的源码解析,笔者已经写过,这里不在重复介绍.

    HashSet-集合

    如果你需要判断一个集合中是否有重复的元素,那么HashSet就是最适合的集合类。

    HashSet<Integer> hashSet = new HashSet<>();
    hashSet.add(1);
    hashSet.add(1);
    hashSet.add(1);
    hashSet.add(1);
    System.out.println("当前集合中的元素个数为:" + hashSet.size());
    

    当前集合中的元素个数为:1

    • 如果要访问集合中的元素,需要使用迭代器进行访问。
    • 对于插入集合中的元素,是不保证顺序性的。
    • 这里要注意一点,HashSet是依托HashMap实现去重的,如果我们往HashSet里存放的是对象,一定要记得重写hashCode和equals方法.

    实现的原理

    其实不用看很多,HashSet内部声明了一个HashMap类型的变量map,每次都委托HashMap做去重.

    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
    
        private transient HashMap<E,Object> map;
        
        
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
        
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
    }
    

    TreeMap-自然数排序的Map

    TreeMap中的元素需要实现Comparable(我们平时使用的包装类型自己帮我们实现了),这里我们尝试乱序插入,然后看看输出的结果

    TreeMap<Integer, String> treeMap = new TreeMap<>();
    treeMap.put(1, "我是1");
    treeMap.put(3, "我是3");
    treeMap.put(2, "我是2");
    treeMap.forEach((k, v) -> System.out.println(k + "," + v));
    
    • 输出结果
    1,我是1
    2,我是2
    3,我是3
    

    可以看到,key按照compare比较后的结果进行了排序.

    LinkedHashMap-插入有序的Map

    前面我们了解到,HashMap是无序的,但是某些场景下,我们希望元素按照插入的顺序进行读取,这个时候你就可以用上LinkedHashMap.
    LinkedHashMap内部使用了一个双向链表维护了key的顺序性.

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
    {
        /**
         * The head (eldest) of the doubly linked list.
         */
        transient LinkedHashMap.Entry<K,V> head;
    
        /**
         * The tail (youngest) of the doubly linked list.
         */
        transient LinkedHashMap.Entry<K,V> tail;
    
        /**
         * The iteration ordering method for this linked hash map: <tt>true</tt>
         * for access-order, <tt>false</tt> for insertion-order.
         *
         * @serial
         */
        final boolean accessOrder;
        // 省略
    }
    

    HashMap留了几个方法给子类进行扩展:

    // Callbacks to allow LinkedHashMap post-actions
    void afterNodeAccess(Node<K,V> p) { }
    void afterNodeInsertion(boolean evict) { }
    void afterNodeRemoval(Node<K,V> p) { }
    

    有兴趣了解原理的,这里提供一下链接,文章只做简单的演示(因为用的确实不多,而且八股文考试很少考):
    彻底理解HashMap及LinkedHashMap

    • Demo
    LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
    linkedHashMap.put("我是第一个", "111");
    linkedHashMap.put("我是第二个", "222");
    linkedHashMap.put("我是第三个", "333");
    linkedHashMap.forEach((k, v) -> System.out.println(k + ":" + v));
    
    • 输出结果
    我是第一个:111
    我是第二个:222
    我是第三个:333
    

    可以看到,我们以什么顺序插入,就按什么顺序输出了结果。

    总结

    • Map 是一种将对象(而非数字)与对象相关联的设计,也就是key-value。
    • HashMap 专为快速访问而设计,而 TreeMap 保持键始终处于排序状态,所以没有 HashMap 快。 LinkedHashMap 按插入顺序保存其元素,但使用散列提供快速访问的能力.

    相关文章

      网友评论

        本文标题:[Java]重学Java-Map

        本文链接:https://www.haomeiwen.com/subject/lvaosrtx.html