Collection接口实现类的特点
public interface Collection<E> extends Iterable<E>
- Collection实现子类可以存放多个元素,每个元素可以是Object
- 有些Collection的实现类,可以存放重复的元素,有些不可以
- 有些Collection的实现类,有些是有序的(List),有些不是有序的(Set)
- Collection接口没有直接的实现子类,是通过它的子接口Set 和 List 来实现的
常用方法
- add:添加单个元素
- remove:删除指定元素
- contains:查找元素是否存中
- size:获取元素个数
- isEmpty:判断是否为空
- clear:清空
- addAll:添加多个元素
- containsAll:查找多个元素是否都存在
- removeAll:删除多个元素
Iterator 迭代器
- Iterator对象称为迭代器,主要用于遍历Collection 集合中的元素。
- 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。
- Iterator 的结构
- Iterator 仅用于遍历集合, Iterator 本身并不存放对象。
Iterator iterator = coll.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
iterator = coll.iterator();
for (Object o : coll) {
System.out.println(o);
}
List 接口和常用方法
List接口是Collection 接口的子接口
- List 集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
- List 集合中每个元素都有其对应的顺序索引,即支持索引
- List 容器中的元素都对应一个整数型的序号记载其在容器重点位置,可根据序号存取容器中的元素
- JSK API中List 接口的实现类常用的有:ArrayList、LinkedList 和 Vector。
ArrayList
- permits all elements, including null,ArrayList 可以加入null,并且多个
- ArrayList 是由数组来实现数据存储的
- ArrayList 基本等同于Vector,除了ArrayList 是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList
ArrayList 底层结构
- ArrayList 中维护了一个Object 类型的数组elementData
transient Object[] elementData;
? 创建一个空的elementData数组={}:
? 执行add,先确定是否要扩容,然后再执行赋值:
? 该方法确定minCapacity,第一次扩容为10
? modCount++ 记录集合被修改的次数,如果elementData 的大小不够,就调用grow() 扩容:
? 使用扩容机制来确定要扩容到多大,扩容使用Arrays.copyOf():
- 如果使用的是指定大小的构造器,则初始elementData 容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍
Vector
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
- Vector 底层也是一个对象数组,protected Object[] elementData;
- Vector 是线程同步的,即线程安全,Vector 类的操作方法带有synchronized
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
- 在开发中,需要线程同步安全时,考虑使用Vector
- Vector 和 ArrayList 的比较
| 底层结构 | 版本 | 线程安全(同步)效率 | 扩容倍数 |
---|
ArrayList | 可变数组 | jdk1.2 | 不安全,效率高 | 如果有参构造1.5倍 如果是无参 1.第一次10 2.从第二次开始按1.5倍扩容 | Vector | 可变数组 Object[] | jdk1.0 | 安全,效率不高 | 如果是无参,默认10,满后按2倍扩容 如果按指定大小,则每次直接按2倍扩容 |
LinkedList
- LinkedList 实现了双向链表和双端队列特点
- 可以添加任意元素(元素可以重复),包括null
- 线程不安全,没有实现同步
LinkedList 的底层操作机制
- LinkedList 底层维护了一个双向链表
- LinkedList 中维护了两个属性first 和 last分别指向首节点和尾节点
- 每个节点(Node对象),里面又维护了prev,next,item 三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表
- 所以LinkedList 的元素添加和删除,不是通过数组完成,相对来说效率较高
ArrayList 和 LinkedList 的比较
| 底层结构 | 增删的效率 | 改查的效率 |
---|
ArrayList | 可变数组 | 较低 数组扩容 | 较高 | LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |
如何选择ArrayList 和 LinkedList:
-
如果改查的操作多,选择ArrayList -
如果增删的操作多,选择LinkedList -
一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList -
在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另一个模块是LinkedList ArrayList 和 LinkedList: -
如果改查的操作多,选择ArrayList -
如果增删的操作多,选择LinkedList -
一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList -
在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另一个模块是LinkedList -
两个线程都不安全
|