集合类 :动态的对象数组
两大核心接口:Collection、Map
本篇博客主要介绍:Collection 接口
1、 定义:
- public interface Collection<E> extends Iterable<E> (JDK1.5之前直接定义 Iterator<E> iterator())
- public interface Iterable<T> (Collection 实现此接口,可以使用foreach循环; Iterator<T> iterator())
2、此接口的两大子接口:
- List接口 :
常用方法:
get (int index):根据索引取得元素
set (int index ,E element):修改指定索引内容,返回修改之前内容
三实现类:
(1)ArrayList实现类(90%):底层为数组
(2)Vector 实现类(JDK1.0):底层为数组
(3)LinkList实现类(8%): 底层为链表
两大区别:
ArrayList 与Vector 区别:版本;ArrayList采用异步处理,效率高,线程不安全,Vector 采用同步处理,效率低,线程安全(主要只用对象锁);ArrayList 支持Iterator、LIstIterator、foreach 输出,Vector 支持以上三种还支持Enumeration 输出;
LInkList 与ArrayList区别:ArrayList 采用数组,LinkList 采用链表;ArrayList适用于频繁查找 的场景,LinkList适用于频繁修改的场景。
- Set接口 :(没有Value值的Map)
常用子类:
(1)HashSet(无序存储):底层为数组 ——本质是HashMap
允许为NULL,且不能重复,元素乱序存储。判断重复 hashCode()+equals()
(2)TreeSet(有序存储) :底层是红黑树 ——本质是TreeMap
不允许为NULL,按序存储。(顺序可自定义)
3、集合输出:(四种)
- Iterator (迭代器输出,从前向后输出)
hasNex():判断是否有下个元素
next () :取得当前元素
remove():删除当前元素
- ListIterator (双向迭代器,List接口独有)——必须先从前往后遍历一遍
hasPrevious():判断是否有上个元素
previous():取得上个元素
- Enumeration (枚举输出)
hasMoreElement ():判断是否有上个元素
nextElement ():取得元素 - foreach输出
4、同步修改引出两大机制:(在一个或多个线程遍历的同时另外一个线程修改该集合结构)
- fail-fast 机制:(常见类集都会出现,只要有Modcount)
目的:保证数据安全性
形成原因:
expectedModcount :调用Iterator取得的迭代器个数;
Modcount :描述集合被修改的次数(默认为零);
在函数调用过程中,在迭代器内部产生 expectedModcount与 Modcount不相等时,就会产生 CurrentModificationException(快速失败机制);
解决办法:
并发遍历集合时,不要修改集合;
调用 failsafe 类集(copyOnWriterArrayList、concurrentHashMap) - fail-safe 机制:(均为线程安全集合)
工作原理:对任何集合构造的修改都会复制到新的集合上进行修改,因此不会抛出快速失败异常
(本质是没有更改原元集合)
存在的问题:
需要复制集合,产生大量的无效元素,开销大;
无法保证读取的数据就是当前原数据结构中的数据;
copyOnWriterArrayList:使用Lock锁实现线程安全
5、List集合自动扩容(ArrayList ,Vector):
- ArrayList :(初始化为空数组)
扩容策略 ——增加50%(扩容后变为原来的1.5倍)
int newCapacity = oldCapacity + (oldCapacity >> 1) - vector :(初始化大小为10)
扩容策略 ——增加1倍(默认扩容后变为原来的2倍)
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity)
- 扩容本质 (创建新数组):Arrays.copyOf(elementData, elementCount)