Java基础-集合
文章目录
1. 集合是什么
1.1集合是什么?
- Java集合是一个 容器,一个典型的泛型实现,能够放置各种类型的数据。分为两类Collection和Map
- 用的IDEA 社区版,ctrl + shift + alt + U 无法自动生成类图,就不贴图类图了
2.Collection
2.1 List
- 通用知识:List是列,允许重复元素。List是结构,扩展了Collection接口(注意Collections是工具类),其元素是有序的,按照插入顺序排。可以有数组实现或链表实现
2.1.1 ArrayList
- 底层实现是数组,更准确的树是Object[]数组
- 线程不安全,线程安全请使用CopyOnWriteArrayList
- 初始容量是10,也可以构造的时候自己指定
- add方法(核心方法)的时候回先判断是否需要扩容,如果需要择进行扩容,其扩容倍数是1.5(
int newCapacity = oldCapacity + (oldCapacity >> 1);
)原容量+原容量右移移位。同时将元素迁移到新数组。通过查看原代码得知,迁移元素用的native本地方法,效率应该还可以。难怪ArrayList用的比较多 - remove方法,会也会移动元素
- 随机查询get方法,因为是的数组,随机查相对链表就很快了
- 遍历 itreator(我们用的 for each)是通过内部类实现。到时候再写篇文客讲内部类
2.1.2 LinkedList
- 底层是双向链表(Node是私有的静态内部类)
- 线程不安全
- 没有ArrayList出场的多。一般是用来做队列,栈的基础数据结构用
2.1.3 Vector
- 线程安全的ArrayList
- 已被过时,如果要求线程安全使用CopyOnWriteArrayList
- 过时原因是其线程安全就是在在相关方法上添加synchronized关键字,直接锁整个对象。多线程用这个效率低下
2.1.4 CopyOnWriteArrayList
- 线程安全的容器,取代Vector
- 锁添加在方法里面,仅锁部分代码块。
- COW机制,写入在副本写入,然后再把副本合并到原本上去
2.2 Set
- 集。和名字一样,是没有重复元素的,其底层就是对于的Map。或者说就是Map里面的K,其中V是new Object()
2.2.1 HashSet
- 参考HashMap
2.2.2 LinkedHashSet
- 参考LinkedHashMap
2.2.3 TreeSet
- 参考TreeMap
3.Map
3.1 HashMap
- 底层是数组+链表 (这个时候需要盗一张图来)
- 实现Map接口,同时还实现了Serializable与Cloneable(不看源码我还不知道有后面这个两个东西)
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}
- 线程不安全,线程安全需要使用ConcurrentHashMap
- 无序
- JDK1.7有比较大的更新:1.将头插法改为尾插法,2.如果容量超过64且某个桶超过8就会变成红黑树
- 默认初始大小是16,默认扩容因子是0.75
- 扩容是大小为原来的两倍
newThr = oldThr << 1
- 构造函数可以修改初始大小。但是给的初始大小一定是2的幂指数(例如初始化使用的是59,实际上会给的64),因为这样方便计算hash的槽
- hash槽计算方式 下次再补充
3.2 LinkedHashMap
- 有序 最近被处理过得排在最后
- 在HashMap的基础上每个节点多了两个指针,分别指向前一个节点,与后一节点
- 默认是插入如的顺序,但是做了查询之后会更新顺序
3.3 TreeMap
- 有序
- 红黑树实现
- 具体细节下次再补充,耗时太长了,先休息
3.4 HashTable
- 线程安全的HashMap
- 已过时,推荐用ConcurrentHashMap
3.5 ConcurrentHashMap
- 并发包的时候再想想写
4.小结
- 最常用的是HashMap和ArrayList
- 面试同时会问很多ConcurrentHashMap和CopyOnWriteArrayList
- ArrayList底层是数组,线程不安全,其初始容量是10,初始化可以指定大小,其扩容倍数的1.5
- HashMap底层是数组+链表,线程不安全,初始容量是16,初始化可以给定参考大小,真正容量是2幂指数倍(与分配Hash槽有关),默认扩容因子是0.75 。扩容倍数是2。
- Set全部是通过对于的Map实现的。简单树就是Map里面的K,其V存储的new Object()
- LinkedList是链表实现,不过用的非常少(反正我目前没有在实际场景中用过)
- Vector和HashTable都是被线程安全的,同时都是被淘汰的。其淘汰原因是效率太低。被CopyOnWriteArrayList 与 ConcurrentHashMap取代
- LinkedListHashMap最后的节点是最近用过的节点。一般用来标记热点数据,淘汰开始节点的数据
5.题外吐槽
- 写了这么晚,才勉强能够完成昨天的任务,太难了
- 本来是通过脑图大纲来写博客,写写博客过程中又发现脑图知识点有缺陷,互相补充,写博客还是能够达到很好的复习效果的
- 明天打算介绍下 虚拟机, 树(AVL二叉树,红黑树,B树,B+树),Redis