ArrayList和LinkedList的大致区别如下:
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
ArrayList<String> mList = new ArrayList<String>();
创建ArrayList对象
/**
* Constructs a new {@code ArrayList} instance with zero initial capacity.
*/
public ArrayList() {
array = EmptyArray.OBJECT; //EmptyArray.OBJECT = new Object[0];
}
添加一个元素 mList.add(str);
/**
* Adds the specified object at the end of this {@code ArrayList}.
*
* @param object
* the object to add.
* @return always true
*/
@Override public boolean add(E object) {
Object[] a = array;
int s = size;
if (s == a.length) { //数组空间满时 s == a.length 成立
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ? //创建一个对象数组,size = 0,初始大小 MIN_CAPACITY_INCREMENT = 12
MIN_CAPACITY_INCREMENT : s >> 1)]; //后续数组填满,重新创建 s + s >> 1,即1.5倍于之前的数组空间
System.arraycopy(a, 0, newArray, 0, s); //copy数据到新数组空间
array = a = newArray;
}
a[s] = object;
size = s + 1;
modCount++;
return true;
}
只要ArrayList的当前容量足够大,add()操作的效率非常高的。只有当ArrayList对容量的需求超出当前数组大小时,才需要进行扩容。扩容的过程中,会进行大量的数组复制操作。
增加元素到任意位置
@Override public void add(int index, E object) {
Object[] a = array;
int s = size;
if (index > s || index < 0) {
throwIndexOutOfBoundsException(index, s);
}
if (s < a.length) {
System.arraycopy(a, index, a, index + 1, s - index);
} else {
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index); //数组重组,效率低
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}
ArrayList插入任意位置时,
@Override public E remove(int index) {
Object[] a = array;
int s = size;
if (index >= s) {
throwIndexOutOfBoundsException(index, s);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
System.arraycopy(a, index + 1, a, index, --s - index); //数组重组,效率低
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return result;
}
删除元素
@Override public E remove(int index) {
Object[] a = array;
int s = size;
if (index >= s) {
throwIndexOutOfBoundsException(index, s);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
System.arraycopy(a, index + 1, a, index, --s - index); //删除元素也是数组重组,效率较低,尤其是index靠前时
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return result;
}
容量参数
ArrayList容量参数比较重要,合理的设置容量参数,可以减少数组扩容的次数,从而提高性能
随机访问 通过数据,效率高
@SuppressWarnings("unchecked") @Override public E get(int index) {
if (index >= size) {
throwIndexOutOfBoundsException(index, size);
}
return (E) array[index];
}
LinkedList<String> mList = new LinkedList<String>();
内部维护了链表
public LinkedList() {
voidLink = new Link<E>(null, null, null); //创建链表
voidLink.previous = voidLink;
voidLink.next = voidLink;
}
private static final class Link<ET> {
ET data;
Link<ET> previous, next;
Link(ET o, Link<ET> p, Link<ET> n) {
data = o;
previous = p;
next = n;
}
}
增加元素 链表操作,添加到链表末尾
@Override
public boolean add(E object) {
return addLastImpl(object);
}
private boolean addLastImpl(E object) {
Link<E> oldLast = voidLink.previous;
Link<E> newLink = new Link<E>(object, oldLast, voidLink);
voidLink.previous = newLink;
oldLast.next = newLink;
size++;
modCount++;
return true;
}
随机添加元素
@Override
public void add(int location, E object) {
if (location >= 0 && location <= size) {
Link<E> link = voidLink;
if (location < (size / 2)) { //查询添加元素的邻居
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
Link<E> previous = link.previous;
Link<E> newLink = new Link<E>(object, previous, link); //链表操作,效率高
previous.next = newLink;
link.previous = newLink;
size++;
modCount++;
} else {
throw new IndexOutOfBoundsException();
}
}
删除元素 remove 链表操作
@Override
public E remove(int location) {
if (location >= 0 && location < size) {
Link<E> link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
Link<E> previous = link.previous;
Link<E> next = link.next;
previous.next = next;
next.previous = previous;
size--;
modCount++;
return link.data;
}
throw new IndexOutOfBoundsException();
}
@Override
public boolean remove(Object object) {
return removeFirstOccurrenceImpl(object);
}
随机访问 需要遍历 效率较低
@Override
public E get(int location) {
if (location >= 0 && location < size) {
Link<E> link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
return link.data;
}
throw new IndexOutOfBoundsException();
}