共同学习Java源代码-数据结构-LinkedHashMap(一)

本文详细解析了LinkedHashMap的实现原理,包括其内部结构、节点操作方法等,并对比了它与HashMap的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class LinkedHashMap<K,V>
    extends HashMap<K,V>

    implements Map<K,V>

这是按顺序存取的HashMap 继承自HashMap 实现了Map接口


    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;
        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }

这是键值对内部类 HashMap的TreeNode就是继承这个类 

这个类继承自HashMap的Node内部类 多了before和after两个属性 调用父类的构造方法


    transient LinkedHashMap.Entry<K,V> head;

    transient LinkedHashMap.Entry<K,V> tail;

head和tail节点

   

    final boolean accessOrder;

这个为false的话 就是按照插入顺序排序 为true的话就是按照访问顺序排序


    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;
        }
    }

这个方法就是将参数p放到尾部的方法 

首先判断最后一个节点是否为空 如果为空 就将p赋给head 否则就将p放到队尾


    private void transferLinks(LinkedHashMap.Entry<K,V> src,
                               LinkedHashMap.Entry<K,V> dst) {
        LinkedHashMap.Entry<K,V> b = dst.before = src.before;
        LinkedHashMap.Entry<K,V> a = dst.after = src.after;
        if (b == null)
            head = dst;
        else
            b.after = dst;
        if (a == null)
            tail = dst;
        else
            a.before = dst;
    }

这个方法是将键值对进行重链接的方法

首先将参数src的before和after属性赋给参数dst的before和after属性

判断如果复制后dst的before为空 那么dst赋给head节点 否则将dst的before节点的after属性赋为dst

判断如果复制后dst的after为空 那么dst赋给tail节点 否则将dst的after节点的before属性赋为dst 

其实就是用dst替掉src


    void reinitialize() {
        super.reinitialize();
        head = tail = null;
    }

这个方法就是重写HashMap的清空所有属性方法 调用了父类的方法 然后把head和tail都清空了


    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;
    }

这个方法是创建新节点的方法 

就是创建一个新的Entry对象 然后调用linkNodeLast放在队尾


    Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
        LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
        LinkedHashMap.Entry<K,V> t =
            new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next);
        transferLinks(q, t);
        return t;
    }

这个是替换节点的方法 创建一个新节点包装了参数p的哈希值 键和值 用新包装的对象替掉p 其实变化的就是next赋给了新节点t的next

 

    TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {
        TreeNode<K,V> p = new TreeNode<K,V>(hash, key, value, next);
        linkNodeLast(p);
        return p;
    }


    TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
        LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
        TreeNode<K,V> t = new TreeNode<K,V>(q.hash, q.key, q.value, next);
        transferLinks(q, t);
        return t;
    }

这两个是树节点的相关方法和上面一样 不说了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值