1. Collection 接口
// Collection 接口在其源码中的定义:
* 1. Collection 是集合层次结构中的根接口
* 2. 一个 Collection 代表 一组对象(objects),这些对象称为其元素(elements)
* 3. 一些 Collection 允许有重复的元素,而另一些 Collection 不允许有重复的元素
* 4. 一些 Collection 的元素是有序的,而另一些 Collection 是无序的
* 5. JDK 没有提供任何直接(direct)实现 Collection 的类
* 6. JDK 只提供了继承 Collection 的“子接口”(List 和 Set)的实现类
* -Set 中的元素没有顺序且不可以重复
* -List 中的元素有顺序且可以重复
* -Map 接口定义了存储 “键(key)- 值(value)映射对” 的方法,键(key)不能重复,重写 hashCode() 和 equals() 方法!
*
* * 接口 Collection
* / \
* * 接口 Set List Map
* | / \ |
* * 类 HashSet ArrayList LinkedList HashMap
// 谈到 Collection 接口,我们不得不区别一下 Collections 类
// Collections 是一个类,不能实例化,是一个工具类,它包含各种有关集合操作的静态(static)多态方法,比如 sort、search、shuffle 以及线程安全等操作
public class Collections {
// 私有化构造器,所以不能被实例化
private Collections() {
}
...
}
2. ArrayList
1. ArrayList 是 List 接口的实现类,并继承于 AbstractList(AbstractList 继承于 AbstractCollection,并且实现了大部分 List 接口)
2. ArrayList 的底层实现是动态数组(属于数据结构中的可扩容的线性表),线程不安全,效率高
// 创建
List list = new ArrayList();
// 常用方法
list.size();// 返回元素的数量
list.isEmpty();
list.add(element);
list.add(index, element);// 在指定位置添加元素
list.remove(index);// 删除指定索引的元素,并返回该元素内容
list.remove(element);// 删除指定元素,删除成功返回 true
list.get(index);// 获取指定位置的元素
list.toArray();// 返回一个包含列表中的所有元素的数组
list.contains(element);// 判断是否包含指定元素
list.indexOf(element);// 返回指定元素所在的第一个位置,没找到返回 -1
list.lastIndexOf(element);// 返回指定元素所在的最后一个位置
list.clear();// 删除所有元素
// 为了更深入了解 ArrayList,我们来分析一下 ArrayList 的部分源码
![]()
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final int DEFAULT_CAPACITY = 10;// 默认容量为 10
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 最大容量
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;// 可见底层是 Object 对象数组
private int size;// 包含元素的数量
// 无参构造器,对象数组默认为空
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 有参构造器,用于初始化数组容量
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
// 返回所包含元素的数量
public int size() {
return size;
}
// 判断对象数组是否为空
public boolean isEmpty() {
return size == 0;
}
// 返回一个包含列表中的所有元素的数组
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
// 删除元素
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null;
return oldValue;
}
// 添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1);// 判断是否需要扩容
elementData[size++] = e;
return true;
}
// 判断是否需要扩容
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 扩容方法
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
...
}
ArrayList