美文网首页
<> linkedhashmap如何保证有序

<> linkedhashmap如何保证有序

作者: monk87 | 来源:发表于2019-06-03 21:16 被阅读0次

    LinkedHashMap这个基础类,默认支持按照插入的书序去访问.这个是怎么做到的 ?
    其实很简单 ,就是这个类内部维护了一个双向链表.有了这个双向链表,往前往后都很好控制顺序.

    //看一个测试代码
    LinkedHashMap<String, String> s = new LinkedHashMap<>();
            //
            s.put("a", "1");
            s.put("b", "2");
            s.put("c", "3");
            //
            Iterator<Map.Entry<String, String>> iterator = s.entrySet().iterator();
            //输出了顺序 a,b,c
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                System.out.println("kv: " + next.getKey() + " : " + next.getValue());
            }
    

    这个是怎么实现的 ? 首先他继承 HashMap, hashmap再put的时候,linkedhashmap重写了构建node部分

    //新建一个node
     Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
            LinkedHashMap.Entry<K,V> p =
                new LinkedHashMap.Entry<K,V>(hash, key, value, e);
            linkNodeLast(p);
            return p;
        }
    //构建自身的链表
    // link at the end of list
        private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
            LinkedHashMap.Entry<K,V> last = tail;
            tail = p;
            if (last == null)
                head = p;
            else {
                p.before = last;
                last.after = p;
            }
        }
    

    完成了这个 之后,在访问的时候就可以使用这个链表了 .请看下面分析

    首先自己实现了 LinkedEntrySetLinkedHashIterator

      final class LinkedEntrySet extends AbstractSet<Map.Entry<K,V>> {
            public final int size()                 { return size; }
            public final void clear()               { LinkedHashMap.this.clear(); }
            public final Iterator<Map.Entry<K,V>> iterator() {
                return new LinkedEntryIterator();
            }
            public final boolean contains(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Map.Entry<?,?> e = (Map.Entry<?,?>) o;
                Object key = e.getKey();
                Node<K,V> candidate = getNode(hash(key), key);
                return candidate != null && candidate.equals(e);
            }
            public final boolean remove(Object o) {
                if (o instanceof Map.Entry) {
                    Map.Entry<?,?> e = (Map.Entry<?,?>) o;
                    Object key = e.getKey();
                    Object value = e.getValue();
                    return removeNode(hash(key), key, value, true, true) != null;
                }
                return false;
            }
            public final Spliterator<Map.Entry<K,V>> spliterator() {
                return Spliterators.spliterator(this, Spliterator.SIZED |
                                                Spliterator.ORDERED |
                                                Spliterator.DISTINCT);
            }
            public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
                if (action == null)
                    throw new NullPointerException();
                int mc = modCount;
                for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after)
                    action.accept(e);
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    
     final class LinkedEntryIterator extends LinkedHashIterator
            implements Iterator<Map.Entry<K,V>> {
            public final Map.Entry<K,V> next() { return nextNode(); }
        }
    

    可以看到调用的时候根据entryset拿到iterator之后 返回的是自己类的iteraotr,重写了 next()函数,直接调用
    nextNode(). 请看下nextndoe

     final LinkedHashMap.Entry<K,V> nextNode() {
                LinkedHashMap.Entry<K,V> e = next;
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                if (e == null)
                    throw new NoSuchElementException();
                current = e;
                next = e.after;
                return e;
            }
    

    可以看到 .其实就是再访问自己构建的这个链表

    相关文章

      网友评论

          本文标题:<> linkedhashmap如何保证有序

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