java集合

Java集合

1. list 和 set 的区别

list 有序 可重复

set 无序 不可重复

2. Collections 和 Collection 的区别

java 工具类的命名 习惯 + s

Collections 集合工具类

Collection 集合顶层接口

3. ArrayList 和 LinkedList 区别

  1. 底层数据结构的差异

ArrayList, 底层是数组, 连续的一块内存空间

LinkList, 底层为双向链表, 不是连续的内存空间

  1. 一个常规结论

ArrayList , 查询速度快(下标), 因为是连续的内存空间,方便寻址,但删除,插入(除尾节点以外)的元素慢,因为需要发生数据迁移。

LinkedList, 查找慢,因为需要通过指针一个一个寻址,但删除和插入快,因为只要改变前后节点的指针指向即可。

  1. ArrayList 的默认长度为10

4. HashMap

4.1 java 7 HashMap

经典哈希表的实现: 数组 + 链表

问题

  1. 容易碰到死锁。

​ https://coolshell.cn/articles/9606.html

​ java 7 经典HashMap实现方式(数组加链表)在多线程环境下,有可能会将链表成环,造成死锁。

​ 2 .潜在安全隐患

致命缺陷:哈希值的碰撞。

​ 可以通过精心构造的恶意请求引发Dos, 链表性能退化

4.2 java 8 HashMap

数组+红黑树

扩容时插入顺序的改进

链表扩容时是保持顺序的,因为扩容的原理为将数组扩充两倍,计算所属桶的时候只会比较最高位是0还是1,也就是将原先的一组链表拆为两个链表,此时的链表顺序是一致的,避免了java7中出现的死锁问题。

4.3 基础

  • aspmap默认的初始容量 1 << 4 , 16
  • 初始化HashMap时,空间未开辟,只要当你第一次向HashMap里put元素的时候,该空间才会被开辟。

4.4HashMap的数组大小为什么一定是2的幂

  1. 个人是可以对HashMap数组的长度进行更改,但该源码中将该长度向上取2的幂,所以无论将该数组大小改成什么结果一定是2的幂。
  2. 将元素放到哪一个HashMap数组表里,比如初始的HashMap数组长处为16,那将元素放到0-15哪一个下标里。

计算方式

​ 首先得到元素的HashCode,

   ```java

int hashCode = hash(key);
int i = indexFor(hashCode, table.length);

static int indexFor(int hashCode, int length) {
return hashCode & (length - 1);
}

// 为什么一定要让HashMap 的数组长度一定是2的幂, 就是为了让(length - 1)达到全是1的效果, 按位与的话就是
// hashCode的2进制的后几位。

// 如果数组长度不是2的幂, 就意味着(length - 1)之后某一位会出现0, 这就意味着无论谁对它进行按位与,出现0
// 的位与之后都是0,那么有些数组将永远为空。
```

4.5 HashMap什么时候开始扩容

HashMap的负载因子,默认为0.75

当添加的数量大于容量*负载因子时,就会开始扩容。 扩容为现在数组长度的2倍。保证其长度为2的幂。

例如:默认为16 , 但是当向HashMap里添加超过12 个时,就会开始扩容。

4.6 为什么HashMap中链表转红黑树的阀值是8

在JDK1.8以后,HashMap中引入红黑树,主要原因为:
当一个桶(Bucket)中的元素过度填充时,链表的查找效率将会大大下降,因此在适当的时候,转换链表为红黑树,可以在桶过度填充时提高查询效率。

在单个桶bin被过度填充时,会被转换为TreeNode的红黑树。通常情况下,单个bin并不会被过度填充,但是不能排除使用恶意或者不合理的hash算法使得键出现O(log n)的极端情况,在这种情况下,将其转换为树形结构后多出来的复杂性也是可以理解的。

因为树节点的带下是普通节点的两倍,所以我们只有在单个桶已经包含了足够多的节点时才会转换成树,而在树变得太小时,将其转换为链表。在hashcode分布良好的情况下,我们是用不到树型桶的。

理想情况下,随机的hashcode遵循Poisson分布原则,在给定参数值的情况下,8的对应的分布值已经相当低,在取值方便于后面的位运算的情况下,取值为2的幂次方是很有必要的,两个要求之下,只有8是最适合的。且用户自定的值不应当小于8,避免分布集中。
    
     * 0:    0.60653066
     * 1:    0.30326533
     * 2:    0.07581633
     * 3:    0.01263606
     * 4:    0.00157952
     * 5:    0.00015795
     * 6:    0.00001316
     * 7:    0.00000094
     * 8:    0.00000006

5. HashSet的存储原理

hashset底层使用hashMap, 存储值作为Key, Value 为创建的一个Object对象

6. ArrayList vs Vector

ArrayList 线程不安全, 效率高,常用

Vector 线程不安全,效率低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值