Collection是[收集品]的意思,这里称[容器],是java中的一个接口,位于java.util包下 Collection下有三大接口:List(列表)、Set(集合)、Queue(队列)
Collection.png 容器接口子类及方法.pngList:列表,顾名思义是一种表结构,核心方法: 按索引插入元素 void add(int var1, E var2) 按索引删除元素 E remove(int var1); 按索引修改元素 E set(int var1, E var2) 按索引查询元素 E get(int var1)
特点: 1.增删改查操作都可以按照索引进行精确的控制,所以是元素的有序排列 2.允许相同元素 List子类.pngList是java中使用频率非常高的一个接口,最要的子类:ArrayList、Vector、LinkedList 1.其中ArrayList、Vector是AbstractList-->AbstractCollection-->Collection 路线 2.LinkedList不止实现了List,还实现了Deque,就像得到两个师傅的真传,招式(方法)更多一些 Queue接口是队列(先进先出),Deque接口(双端队列)是Queue的弟子,两头都能随意进出 所以根据需求即可当栈也可当队列,LinkedList得到了Deque的真传,所以也可以
抽象类一般是先实现接口,或者拓展一些子类公用方法,总之就是把能做的先做了。 有种天下父母心的感觉,就像AbstractList对ArrayList说:我能帮你做的尽量都做了,接下来就看你的了
public abstract class AbstractCollection<E> implements Collection<E> public abstract class AbstractSequentialList<E> extends AbstractList<E> public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>可以说Vector、ArrayList是亲兄弟,LinkedList算个堂兄
项目线程安全?实现扩容定点添加/删除尾添加/删除查询修改ArrayList否数组50%O(n)O(1)O(1)O(1)Vector是数组100%O(n)O(1)O(1)O(1)LinkedList否双链表--O(n)O(1)O(n)O(n)尾添加测试[add(E)]
----复杂度10001000010W100W1000WArrayListO(1)0.0004秒0.0016秒0.0063秒0.0297秒0.6704秒LinkedListO(1)0.0004秒0.0017秒0.0098秒0.2384秒2.4285秒操作数opCount=1000W:插入的位置与耗时比较
----1/93/95/97/98/9ArrayList0.1496秒0.1136秒0.0821秒0.0297秒0.0012秒LinkedList0.0150秒0.0251秒0.0386秒0.0176秒0.0102秒可见ArrayList越往后插入越快,因为要变动的元素越少 LinkedList从两头到中间速度变慢,取决于链表的查询机制,总的来说, 随机添加LinkedList比较有优势些,只是末尾添加ArrayList较好
顺便提一下只有Vector容器对象可以用vector.elements()获取Enumeration对象,其他列表的需要自定义 在合并字节输入流SequenceInputStream时需要传递一个Enumeration对象,Vector有了用处
SequenceInputStream(Enumeration<? extends InputStream> e) Vector类对集合的元素操作时都加了synchronized,保证线程安全。但使得效率下降:如 public synchronized boolean add(E e) { modCount++; add(e, elementData, elementCount); return true; } 所谓同步:即当一个Iterator被正在被使用,另一个线程对Vector添加或删除元素,这时调用Iterator的方法时将抛出异常 public synchronized void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final Object[] es = elementData; final int size = elementCount; for (int i = 0; modCount == expectedModCount && i < size; i++) es[i] = operator.apply(elementAt(es, i)); if (modCount != expectedModCount) throw new ConcurrentModificationException(); modCount++; } 可以看到很多关于修改的方法当:modCount != expectedModCount时都会扔一个ConcurrentModificationException异常 也就是期望的修改次数与真实的修改次数不一致时集合:数学上的集合性质:
确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合 互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。 无序性:一个集合中,每个元素的地位都是相同的,元素之间是无序的。Set的操作比较少,基本上也就是Collection传下来的方法 Set一般基于Map来实现:HashSet、LinkedHashSet、TreeSet的特性,根本上是HashMap、LinkedHashMap、TreeMap的特性
HashSet内部有一个HashMap<E,Object> map成员变量,增删实际上是使用map的方法 按照哈希的顺序:hashCode(),equals(Object obj) 底层实现:HashMap
HashSet.png private transient HashMap<E,Object> map; public HashSet() { map = new HashMap<>(); } public boolean add(E e) { return map.put(e, PRESENT)==null; } public boolean remove(Object o) { return map.remove(o)==PRESENT; }LinkedHashSet是HashSet的子类,源码少得可怜,基本上都是调用父类(HashSet)的构造方法 基于一个由链表实现的哈希表,保留了元素插入顺序 底层实现:LinkedHashMap
LinkedHashSet.pngLinkedHashSet中:
public LinkedHashSet(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor, true); }HashSet中的三参构造
HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }实现NavigableSet:使用元素的compareTo对元素进行排序,也可使用Comparator自定义比较器 TreeSet多拜了一个师傅:NavigableSet-->SortedSet 使用方法也多几个 底层实现:TreeMap
public TreeSet() { this(new TreeMap<>()); } TreeSet.png关于队列,是一直先进先出的线性数据结构,使用场合比较狭窄 子类常见的有PriorityQueue(优先队列)和上文提到的LinkedList。
queue.pngPriorityQueue优先队列,是基于数组实现的二叉堆来实现的特殊队列,具有完全二叉树的性质。 每次从优先队列中取出来的元素要么是最大值或最小值(最大堆/最小堆)
Collection的简单总结就酱紫
1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3---个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持
转载于:https://www.cnblogs.com/toly-top/p/9781859.html