1.ArrayList是实现了基于动态数组的数据结构,LinkedList是基于链表的数据结构
2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据
ArrayList和LinkedList是两个集合类,用于存储一系列的对象引用
时间复杂度:
ArrayList的内部实现是基于基础的对象数组的,因此,它使用get方法访问列表中的任意一个元素时,它的速度要比LinkedList快。
LinkedList中的get方法是按照顺序从列表的一端开始检查,直到另外一端。对于LinkedList,访问列表中的指定元素没有更快的方法。
ArrayList是一个数组队列,提供了相关的添加、删除、修改、遍历等功能
与ArrayList相比,LinkedList的增加和删除对操作的效率更高,而查找和修改的操作效率较低
以下情况使用ArrayList:
频繁访问列表中的某一个元素
只需要在列表末尾进行添加和删除元素操作
以下情况使用LinkedList:
需要通过循环迭代来访问列表中的某些元素
需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素的操作
/**
* Default initial capacity.
* 默认初始容量,ArrayList的默认长度
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
* ArrayList的默认空元素链表
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
* ArrayList存放的数据
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
* ArrayList 的长度
* @serial
*/
private int size;
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
* 初始化一个指定大小容量的列表
*/
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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
* 构造一个 初始化容量为10的空列表
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
* 构造一个 包含指定集合的元素列表,按照它们由集合迭代器返回的顺序
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
ArrayList get函数直接定位获取的方式时间复杂度为O(1),而LinkedList的get函数时间复杂度为o(n).
再结合考虑空间消耗的话,建议首选ArrayList.对于个别插入删除非常多的可以使用LinkedList
结论总结:
1.无论ArrayList还是LinkedList,遍历建议使用foreach,尤其是数据量较大时LinkedList避免使用get遍历。
2. List使用首选ArrayList.对于个别插入和删除非常多的可以使用LinkedList
3. 可能在遍历List循环内部需要使用的下表,这时综合考虑下是使用foreach和自增count还是get方式。
4.ArrayList用来快速定位对象是非常有效率的,但是如果要对ArrayList中间插入和删除,效率会非常低
5.LinkedList对于插入和删除是非常有优势的,反之对于快速定位,是LinkedList的弱项