集合
ArryList(链表都是,包括HashMap)在JDK1.8之前,是使用数组+拉链法解决冲突,现在是长度超过8就使用红黑树存储
红黑树(Red-Black Tree)是一种自平衡的二叉搜索树。在计算机科学中,它是用来组织具有可比较关键字的数据,如关联数组,它在1972年由鲁道夫·贝尔发明。红黑树通过确保从根到叶子的最长的可能路径不多于最短的可能路径的两倍长而近似平衡,这是通过对节点的颜色和对树结构的约束来实现的。如果一个节点是红色的,则它的子节点必须是黑色的
线程安全的集合:
vector、hashtable,不建议单线程使用,有额外开销
集合遍历方式:
1.for循环
2.增强for循环
3.迭代器(适合删除)
4.ListIterator迭代器(双向访问且能修改数据)
5.foreach
6.streamAPI
arrylist不安全的体现
1.部分值为null
2.add的量与size不符合
3.索引越界异常
使其变得线程安全:
1.使用Collections类的synchronizedList方法包装
2.使用Vector替代
3.ConcurrentHashMap 中volatile(保证变量的可见性) + CAS (乐观锁,因为造成hash碰撞的几率较低)或者 synchronized(加锁) 来实现的线程安全的。需要先定位到具体的 Segment,然后再在该 Segment 上加锁
ArryList和LinkedList的区别
1.查询快
2.插入、删除慢
ArryList扩容机制
1.计算扩容大小(一般是1.5倍)
2.申请内存空间并创建ArryList对象
3.复制元素到新内存里
4.替换引用
5.添加新元素
哈希冲突解决
1.链接法
2.开放寻址法
3.再哈希法
4.哈希桶扩容
HashMap不是线程安全的
会出现put方法数据覆盖的问题,保证线程安全需要同步加锁
HashMap的put过程
Hashmap调用Get方法就一定安全吗
不,有可能会发生空指针异常,以及多线程情况下发生的错误结果。
为什么Hashmap用红黑树而不是平衡二叉树
1.平衡二叉树的要求过于严格,左右子树的高度差不允许超过1,几乎每一次插入都会导致失衡而需要时间和内存进行调整
2.红黑树不追求完全平衡,只需要最长路径不超过最短路径的两倍即可,虽然损失一些查询效率,但换取了一些维护的成本
重写HashMap的equal和hashcode方法需要注意什么
1.如果只重写hashcode,当hash值一样的两个键值对,equal的值可能不等,重新存储一遍
2.如果只重写equal,就连哈希函数这一关都过不了,存储一堆相同对象
3.必须保证,equal相等hashcode也相等;hashcode相等,equal不一定相等
HashMap的扩容(初始容量16)
当超过负载因子0.75时
1.和ArryList类似(1.5倍),先开一块2倍内存的新哈希表
2.将原本的内容复制到新表中,旧表回收
新的哈希值映射方法
因为旧的哈希函数取末尾几个为哈希值,当扩容时,只需要计算新增的那一位bit是1的哈希值即可
Set集合有什么特点?如何实现
集合元素不重复
和哈希表类似
有序的Set是什么,记录插入顺序的集合是什么
TreeSet和LinkedHashSet
LinkedHashSet
线程安全的集合是什么
1.vector list子类
2.HashTable(数组+拉链法+全上锁)
并发map
ConcurrentHashMap
ConcurrentSkipListMap
并发set
ConcurrentSkipListSet
并发list
CopyonWriteArryList