集合相关知识

string final,不能追加,需要重新new一个

stringbuild,内容 可变,可以重新赋能,能够追加,空间不足创造一个更大的,然后复制过去

stringbufferbuild 线程安全

javac编译,字符串加号可以进行优化,去掉加号,组成一个字符串。

常量相加,当有变量时,stringbuild方式添加,返回的是堆中的地址

常量有重复,地址不变

加号和append 谁效率高

少量字符串加号

多了就append

集合:集合类存储的仅仅是对象的引用,并不存储对象本身。

Queue:实现栈和队列,

Set:不允许元素重复,通过hash和equls方法判断是否重复

hashcode可能相同,hashset无序,treeset排序,linkedHashset有序

hashset:底层基于hashmap

hashmap:无序

linkehashmap:有序

treehashmap:排序

hashtable和hashmap区别

线程

key是否为空

value是否为空

Hashtable和concurrentmap区别

给方法加了锁,锁的this,当前锁标识对象,锁住整个对象。

在colletiontions中synchronziedmap,将线程不安全的map转换为安全的map,也是锁住整个对象, 效率低

concurrentmap juc中

1.7

分段锁,线程安全,效率好。

1.8

节点锁,各个节点单独加锁。

collections.syncMap 将一个不安全的map加成安全的。

怎么扩容

成倍扩容,新建一个老数组

传入初始容量,向上取。

map遍历,不支持一遍遍历,一遍删除修改,要并发异常。

底层原理

map底层是Node节点,因为它要存key-value

所以map底层其实是Node一个个节点拼成的?

hash计算,hashcode的计算,异或向右16位,右移16位,是为了避免hash冲突,且和原本的hash值

这是它设置的一些默认参数

默认容量16,向左4位,2的四次方,16

最大容量,向左30位,2的三十次方,所以map最大容量就是2的三十次方

默认负载均衡 0.75

差点没认出这三个,相当于一个阈值

TREEIFY_THRESHOLD   链表转树的阈值8
UNTREEIFY_THRESHOLD    树转链表-6
MIN_TREEIFY_CAPACITY  数组长度

转树的条件,数组大于64,链表大于8,两个条件都要满足

ctrl+f12查看当前类的所有方法,hashmap的构造方法

我们可以看到有参构造和无参构造,有参大家都看得懂撒,传入容器大小,然后一个是默认负载均衡0.75

无参我们去看看是怎么回事,只给了个负载均衡参数?应该是个空数组

最重要,问的最多就是hashmap的put和get方法,然后我们去源码看看,put用了putval这个方法,我们点进去看看putval,let is go!

有点长哈,tap是当前链表(其实就是hash表?我觉得就是hash表的意思,我这个不咋自信,不敢确定),node是传入节点

我们对源码进行解析,发现自己一个人还是看的懂的,只要对各个参数的意义理解到就没问题了。

把tablehash表的值赋给tap,判断是不是空,说明链表是空的,创建长度,给hash表,默认16。

不为空,则对p  hash算法计算位置,长度-1余,如果节点没有值,把节点放进去就好了。

有值,对hash值是否一样,key是否一样,一样覆盖就行,然后我们就要判断key和value不相等,,else if 是不是树结构,instanceof,我也没咋懂啥意思,我猜是用来判断是不是TreeNode种类,进行一种种类判断,我觉得这个方法的意思就是这样,不然后面解释不通。是树结构,我们用树结构的put方法,不是则用链表,链表遍历判断,然后放值。

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

有点累了

get方法,列表不能为空

同时列表首节点一致,直接返回,不一致,看树还是链表,树则以树的形式返回,链表则遍历。

    final Node<K,V> getNode(int hash, Object key) {
        Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
        if ((tab = table) != null && (n = tab.length) > 0 &&
            (first = tab[(n - 1) & hash]) != null) {
            if (first.hash == hash && // always check first node
                ((k = first.key) == key || (key != null && key.equals(k))))
                return first;
            if ((e = first.next) != null) {
                if (first instanceof TreeNode)
                    return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                do {
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        return e;
                } while ((e = e.next) != null);
            }
        }
        return null;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值