本专题为Java基础专题,为笔试面试的Java同学们提供参考使用。
01 List框架List存储有序,可重复的元素。
有序即元素按数组的索引顺序依次存储。
02 List中常用API(1) public void add(int index, E element)
在指定index处插入元素element(2) public boolean addAll(Collection extends E> c)
在尾部添加Collection c中所有元素(3) public E get(int index)
获取index处的元素(4) public int indexOf(Object o)
返回o在集合中首次出现的位置,若无则返回-1(5) public int lastIndexOf(Object o)
返回o在集合中末次出现的位置,若无则返回-1(6) public E remove(int index)
删除指定位置的元素,返回被删除的元素(7) public E set(int index,E element)
把index位置的元素改为element,返回修改前的元素(8) public List subList(int fromIndex,int toIndex)
获取子List(左闭右开)
03
ArrayList
1.JDK1.7中
(1) 如果使用空参构造器,即 ArrayList list = new ArrayList<>();
,底层默认创建一个长度为10的Object[ ]的数组。
(2) 自动扩容机制,即往数组中加元素时超出了数组的最大容量,ArrayList会自动扩充容量。默认情况下,容量扩充为原来容量的1.5倍。
(3)扩容完后,使用了Arrays类下的copyOf方法完成对数组中原有数据的复制。
2.JDK1.8中
(1) 异:使用空参构造器,底层并没有创建数组(下方源码第二行),只有在第一次往里面添加元素时,才创建了长度为10的数组。
(2) 其他均与1.7时相同。
以下附上JDK1.8中的ArrayList的部分源码。
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] 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 ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
oldCapacity >> 1 /* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}
04
LinkedList
(1)内部声明了Node类型的first和last,transient Node first;
,transient Node last;
即链表的头结点和尾结点,默认值为null。
(2)内部维护了链表长度size。
以下为LinkedList的部分源码
transient int size = 0;
/**
* Pointer to first node.
*/
transient Node first;/**
* Pointer to last node.
*/transient Node last;private static class Node<E> {
E item;
Node next;
Node prev;
Node(Node prev, E element, Node next) {this.item = element;this.next = next;this.prev = prev;
}
}
05
Vector
(1)使用空参构造器,底层默认创建一个长度为10的数组。
(2)自动扩容机制:默认扩容为原来长度的2倍。
(3)扩容完后,使用了Arrays类下的copyOf方法完成对数组中原有数据的复制。
以下为部分源码
/**
* Constructs an empty vector so that its internal data array
* has size {@code 10} and its standard capacity increment is
* zero.
*/
public Vector() {
this(10);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, /* minimum growth */
capacityIncrement > 0 ? capacityIncrement : oldCapacity
/* preferred growth */);
return elementData = Arrays.copyOf(elementData, newCapacity);
}
06
总结
1.ArrayList底层是一个数组,查询快,插入删除慢,线程不安全。
2.LinkedList底层是一个双向链表,插入删除快,查询慢,线程不安全。
3.Vector底层是一个数组,查询快,插入删除慢,线程安全。
4.在知道大致元素个数时,建议使用带参数的构造器,减少自动扩容次数,提高效率。
END欢迎关注ACJavaBear。
我是小熊,转行Java的化学僧。
ACJavaBear将会被打造成一个Java仓库。
希望帮助和我一样转行学Java的同学们。