JAVA双列集合的简单了解(Map)

目录

HashMap

LinkedHashMap

TreeMap


HashMap

hashmap的组成是数组+链表+红黑树

当我们创建一个HashMap时,它会先自己定义一个加载因子0.75f(默认值),该加载因子的大概意思是当我们存储的数据达到了它的数组百分之75的时候的时候就会扩容,为什么不是存满了再扩容呢?因为它还有一个链表结构,比如它可能存储到百分之90的时候就把数据一直挂在链表上(hash冲突)导致链表过长并提前转成红黑树,因此就需要设置一个阀值,那为什么不是百分之50或者百分之30就扩容,那样会导致内存的浪费。

 当我们调用put(key,value)方法添加数据时,它会先用hash(key)进行哈希运算计算哈希值,尽量减少哈希碰撞。

 具体实现的putVal()方法,它会先创建一个Node类型的数组主要存储hash值、数据和下一个数据。

 然后进行判断是不是需要初始化容量,然后调用resize初始化容量大小为16。

然后在查看hash值所在的节点是否为空(是否有值),为空则将数据存入该节点。

不为空则进行hash值的比较,再进行key值的比较 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))如果都相等就会通过e标记然后进行替换。

否则比较是否树的节点p instanceof TreeNode,是则放入树中。

否则遍历链表的for (int binCount = 0; ; ++binCount)并查找链表的尾节点if ((e = p.next) == null),Node的next是存储下一个数据的,如果为空下一个节点就是最后一个节点,就将数据存入下一个节点。

然后对比链表节点数if (binCount >= TREEIFY_THRESHOLD - 1)如果达到8了就转换成红黑树,但是转换为红黑树还有一个条件,往下拉查看treeifyBin()方法的源码图,就会发现如果数组容量达不到64的化它会进行扩容而不是转换成红黑树MIN_TREEIFY_CAPACITY=64。

最后就是将旧值替换成新值

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

 treeifyBin()方法源码图

 其他方法

remove()  删除

size()  数据数量

get()  根据key获取值

LinkedHashMap

LinkedHasMap他的底层实现差不多用的就是它的父类HashMap的,很多方法都重写了父类的,但是put()方法没有重写,而是直接沿用父类方法,其主要的特点就是维护了一个以父类Node组成的Entry双向链表,他会保持存入的顺序。

TreeMap

treemap是由红黑树组成的,其创建的时候会初始化一个比较器,存储也是以键值对的方式

简单的了解就是:

必须实现Compareable接口;

存储的数据是无序的,但提供排序功能(Comparable接口);

存储的元素不再是唯一,具体结果根据Compare方法来决定;

------------------------深入了解TreeMap-----------------------------

 Java提高篇(二七)-----TreeMap_chenssy 的技术博客-CSDN博客_treemap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值