ArrayList:
特点:继承于AbstractList,它还实现了RandomAccess, Cloneable, java.io.Serializable等接口。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
内容是有序的(插入顺序)并且是允许重复且允许为NULL,集合可 使用clone方法(Cloneable),可以进行序列化操作(Serializable),可以被随机访问(RandomAccess),可以使用迭代器遍历
使用场景:适合于数据不需要做大量的随机插入、删除操作的场景;比较适合数据的随机访问。因为ArrayList的 底层数据结构是数组,进行随机插入、删除操作的时候会涉及到大量的数据元素的移动,这会使效率变低。
源码实现:底层数据结构是数组;初始容量为空,当插入第一个元素时,初始容量为10,当容量满了进行1.5倍扩容;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private void grow(int minCapacity) {
// overflow-conscious code
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);
}
线程是否安全:线程不安全
LinkedList:
特点:继承于AbstractSequentialList,还实现了RandomAccess,Cloneable, java.io.Serializable等接口.
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
内容是有序的(插入顺序)并且是允许重复且允许为NULL,并且可以使用迭代器来遍历
使用场景:不适合数据需要大量的随机访问的操作;适合于数据的随机插入、删除或修改操作。因为LinkedList的底层数据结构是双向链表,进行数据的随机访问的时候,需要从头或者从尾部遍历,这会使效率降低。
源码实现:底层数据结构是双向链表;
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
线程是否安全:线程不安全
Vector:
特点:继承于AbstractList,它还实现了List, RandomAccess, Cloneable, java.io.Serializable等接口。
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
内容是有序的(插入顺序)并且是允许重复且允许为NULL,集合可使用clone方法(Cloneable),
可以进行序列化操作(Serializable),
可以被随机访问(RandomAccess),
可以使用迭代器遍历
使用场景:当有线程安全的需求的时候比较适合使用vector,因为vector是线程安全的集合;而当没有线程安全的需求的时候适合使用ArrayList(效率更高)
源码实现:底层数据结构是数组;初始容量为10,当容量满了之后有两种选择:1、当增长因子小于0的时候直接进行二倍扩容
2、当增长因子大于0的时候,扩大增长因子个大小
与ArrayList相比较,vector的扩容方法更加的合理
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
线程是否安全:线程安全,vector中的所有方法都加了synchronized锁,所以vector是线程安全的集合
Stack:
特点:继承于vector
public
class Stack<E> extends Vector<E>
stack中方法的实现大多是沿用了vector中的方法
数组与集合的区别:
数组:当你创建了一个数组的时候,那么这个数组的容量就已经确定了,无法进行扩容等操作,所以数组比较适合事先就已经知道所要存储的数据元素的数量的情况下使用。与集合相比,数组少了扩容、删除等相关方法,故而数组的效率也更高。
集合:集合在存储数据元素的同时,还添加了许多对数据进行操作的方法,如添加、删除、修改等。像ArrayList这样的底层数据结构是数组的集合,还添加了扩容方法,所以集合有着更加广泛的使用场景。但与普通数组相比,集合的效率较低。
关于集合的一些操作:
1、求两个集合不重复的并集
ArrayList<Integer> list = new ArrayList<>();
list.add(31);
list.add(88);
list.add(789);
list.add(456);
list.add(222);
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(31);
list1.add(222);
list1.add(100);
list.removeAll(list1);//将 list 中与 list1 相同的元素删除
list.addAll(list1);//将 list1 中的所有元素添加入list
2、求两个集合的交集
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(31);
list2.add(88);
list2.add(789);
list2.add(456);
list2.add(222);
ArrayList<Integer> list3 = new ArrayList<>();
list3.add(31);
list3.add(222);
list3.add(100);
list2.retainAll(list3);
3、求两个集合的差集
ArrayList<Integer> list4 = new ArrayList<>();
list4.add(31);
list4.add(88);
list4.add(789);
list4.add(456);
list4.add(222);
ArrayList<Integer> list5 = new ArrayList<>();
list5.add(31);
list5.add(222);
list5.add(100);
ArrayList<Integer> list4c = (ArrayList<Integer>) list4.clone();
ArrayList<Integer> list5c = (ArrayList<Integer>) list5.clone();
list4c.removeAll(list5);//求 list4 有而 list5没有的部分
list5c.removeAll(list4);//求 list5 有而 list4 没有的部分
list4c.addAll(list5c);//将两部分合并起来
for(int i=0;i<list4c.size();i++){
System.out.println(list4c.get(i));
}