写在开头
java.util.Collection 作为 Java 开发最常用的接口之一, 我们经常使用, 今天我带大家一起研究一下 Collection 接口, 希望对大家以后的编程以及系统设计能有所帮助, 本文所研究的 jdk 版本为 jdk1.8.0_131
明确一下几点:
Collection 是接口, 其继承了 Iterable 接口
Collection 属于单值类型集合, 重点子接口 List 接口和 Set 接口
Java.util.List 接口(有序, 不唯一)
ArraryList
ArrayList 是一个数组队列, 相当于 动态数组. 与 Java 中的数组相比, 它的容量能动态增长. 它继承于 AbstractList, 实现了 List, RandomAccess, Cloneable, java.io.Serializable 这些接口. ArrayList 是非同步的, 效率高但是线程不安全, Collections.sychromiziedList(new ArraryList<>()); 可以让那个 ArrayList 变成线程安全类
ArrayList 是基于动态数组实现的, 在增删时候, 需要数组的拷贝复制.
ArrayList 的默认初始化容量是 10, 每次扩容时候增加原先容量的一半, 也就是变为原来的 1.5 倍
删除元素时不会减少容量, 若希望减少容量则调用 trimToSize()
它不是线程安全的. 它能存放 null 值.
LinkedList
LinkedList 是一个双向循环列表队列
LinkedList 是一个继承于 AbstractSequentialList 的双向链表. 它也可以被当作堆栈, 队列或双端队列进行操作.
LinkedList 实现 List 接口, 能对它进行队列操作.
LinkedList 实现 Deque 接口, 即能将 LinkedList 当作双端队列使用.
LinkedList 实现了 Cloneable 接口, 即覆盖了函数 clone(), 能克隆.
LinkedList 实现 java.io.Serializable 接口, 这意味着 LinkedList 支持序列化, 能通过序列化去传输.
LinkedList 是非同步的.
Vector
底层是数组, 现在已少用, 被 ArrayList 替代, 原因有两个:
Vector 所有方法都是同步, 有性能损失.
Vector 初始 length 是 10 超过 length 时 以 100% 比率增长, 相比于 ArrayList 更多消耗内存.
参考资料: https://www.zhihu.com/question/31948523/answer/113357347
总的来说: 查询多用 ArrayList, 增删多用 LinkedList.
ArrayList 增删慢不是绝对的(在数量大的情况下, 会有例外):
如果增加元素一直是使用 add()(增加到末尾)的话, 并且不扩容的情况下)
一直删除末尾的元素也是 ArrayList 要快[不用复制移动位置]
至于如果删除的是中间的位置的话, 还是 ArrayList 要快!
但一般来说: 增删多还是用 LinkedList, 因为上面的情况是极端的~
Java.util.Set 接口(无序, 唯一)
|--SortedSet 接口 --TreeSet 实现类
Set 接口 --|--HashSet 实现类
|--LinkedHashSet 实现类
hashSet
hashSet 底层基于 hashMap 实现, 如图
hashSet 中的 add()方法, 是将对象 E 放入 hashMap 中的 key 的位置, value 位置存放的是一个固定的 Object, 如图:
HashSet 是无序唯一的, 当元素为自定义对象时, 两者的 hashCode 不同, 被认为是不同的元素从而被允许放入 HashSet 中, 但这不符合实际的生产意义, 因此需要让其判定位相等, 就要重写 hashCode(), 然而重写 HashCode(), 会出现重码的 bug, 因此需要重写 equals()来解决
添加元素的时候, 如果 key(也对应的 Set 集合的元素)相等, 那么则修改 value 值. 而在 Set 集合中, value 值仅仅是一个 Object 对象罢了(该对象对 Set 本身而言是无用的).
也就是说: Set 集合如果添加的元素相同时, 是根本没有插入的 (仅修改了一个无用的 value 值), 从源码(HashMap) 中也看出来,== 和 equals()方法都有使用, 具体过程如下
新元素的 hsah 是否等于老元素的 hash, 如果不相等, 则元素不同, 如果相等, 那么进行第二部比较
新元素与老元素用 "==" 进行比较, 如果相等, 则为同一元素, 若不同则进行第三部比较
新元素和老元素用 equals()方法判定是否相等, 如果不等则不是同一元素, 如果相等那么结果为: 两个元素不是同一个对象, 程序想把它们当成同一个对象, 因此重写了 equals 方法;
TreeSet
与 HashSet 是基于 HashMap 实现一样, TreeSet 同样是基于 TreeMap 实现的.
TreeSet 是 SortedSet 接口的唯一实现类, TreeSet 可以确保集合元素处于排序状态. TreeSet 支持两种排序方式, 自然排序 和定制排序, 其中自然排序为默认的排序方式. 向 TreeSet 中加入的应该是同一个类的对象.
LinkedHashSet
LinkedHashSet 是 HashSet 的一个 "扩展版本",HashSet 并不管什么顺序, 不同的是 LinkedHashSet 会维护 "插入顺序".HashSet 内部使用 HashMap 对象来存储它的元素, 而 LinkedHashSet 内部使用 LinkedHashMap 对象来存储和处理它的元素
来源: https://www.cnblogs.com/lsgspace/p/10464757.html