首先List接口与Set接口都是继承自Collection接口,
List
list接口的特点是存放的元素 有序且可重复
主要常用实现类有ArrayList,linkedList,vector
ArrayList:
- 存储结构:一个Object数组,采用默认初始化则默认开辟一个空数组(空数组new Object { } 不是null数组)
- 优缺点:遍历查找速度快,支持随机高效访问,但是删除插入速度较慢。
- 扩容方式:扩容方法grow(); 情况1:当还是空数组的时候添加第一个元素时会直接扩容长度到10。情况2:当元素已满时,再向其添加新的元素时,数组会扩容1.5倍。(扩容后的数组是扩容前的1.5倍)但是最大容量是 Integer.MAX_VALUE - 8和 Integer.MAX_VALUE (即integer的最大值) 下附源码:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//如果需要的最小长度大于了Integer.MAX_VALUE - 8哪么数组长度即等于 Integer.MAX_VALUE否则等于Integer.MAX_VALUE - 8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
linkedList
- 存储结构: 双向链表存储,(1.6之前是双向循环链表,1.7取消了循环)
- 优缺点: 插入删除速度很快,但是遍历速度较慢,不支持随机高效的访问。
- 相对于ArrayList而言,LinkedList消耗的空间要比前者多一点,因为Linked list每个元素都会保存 per(指向前一个元素的指针) item(元素值) next(指向下一个元素)
vector
- 存储结构:vector采用object数组保存数据,采用默认初始化时会直接指定一个长度为10的数组,这也是和ArrayList的一个区别。
- 优缺点: vector因为加上了synchronizaed同步锁,所以线程安全。但是性能会降低一些。
- 扩容方式:扩容方法grow(); vector正常情况下会扩容到原数组的二倍,但是如果我们在初始化的时候自己传入增量,则会按照自己传入的增量来进行扩容;
源码如下:
public Vector(int initialCapacity, int capacityIncrement) {
//初始化数组长度 //增量
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
//用传入的增量代替默认的增量
this.capacityIncrement = capacityIncrement;
}
/*******************选取自扩容代码grow()*************************/
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);
//新的长度的指定方式。
Set
Set接口的特点是:无序且唯一;
主要的实现类: hashset , linkedhashset, treeset
Hashset : 还是使用hashmap(数组+链表+红黑树)实现存储;其实整个set就是一个"伪装"的map 哈哈哈
private transient HashMap<E,Object> map;//set接口中声明的成员变量
private static final Object PRESENT = new Object();//填充value的object类型元素
- *存储结构: set的元素都存储再hashmap的key上,所以key不重复且无序。而hashmap的value处使用一个object类型的静态常量来进行填充。
- hashset可以存储null值,线程不安全;
- hashset如何识别重复元素: 首先当一个对象加入set中时,会计算对象的hashcode值来判断对象加入的位置,如果此位置为空,则加入;如果不为空,就依次比较当前位置所在的链表,如果链表中没有相同的hashcode,代表不重复,如果有相同的hashcode,就调用equals方法检查内容是否一样,内容不一样则添加。
Linkedhashset
- 存储结构:(采用linkedhashmap实现)继承自hashset,且linkedhashset在结构上又加上了链表来记录元素加入的顺序,所以集合变成有序的,
- linkedhashset可以存储null元素。
treeset
- 存储结构:采用treemap(红黑树)存储。是一类有序且可排序的集合,不可存储null元素,否则抛出空指针异常;
- 排序方式两种:
-
*第一种:自然排序,集合元素自己实现comparable接口,重写compareTo方法
-
*第二种:自定义排序,创建set时传入一个自定义的比较器comparator接口,重写compare方法,实现自定义排序
- 优点:查找效率很高;
关于Set的扩容机制就放到Map的总结当中扩展,因为Set其本身实现就是一个Map