小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
1.List
List 有序集合,元素可以重复 他主要的实现类:如ArrayList,LinkedList我们在开发中很常用。 ArrayList,LinkedList有何区别:首先ArrayList他底层是数组实现的,因此他的查询是很快的 而LinkedList底层是链表实现的,因此他的查询比较慢(因为没查询一次要一个个节点往下找),在进行修改是速度就比ArrayList快很多。今天我想先分享ArrayList他的底层基于数组是如何实现操作的
2.ArrayList
在我们声明一个ArrayList数组时我们从源码看出他有一个默认大小为10
transient Object[] elementData;
private int size;
elementData:存储ArrayList元素的数组缓冲区。ArrayList的容量是此数组缓冲区的长度,若没指定长度默认就是10 size: ArrayList的大小(它包含的元素数) 其中有一个关键字:transient 其意思就是 在序列化时 这个属性值就不会被序列化
那我们知道ArrayList是基于数组实现的,那么我们来看一看他是如何添加数据的
- 通过set的方法 将此列表中指定位置的元素替换为指定的元素 elementData[index] = element; 其实就是在替换数组中某个值
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
**
- 在尾部加数据 ** elementData[size++] = e;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
- 将指定的元素插入此文件中的指定位置名单。移动当前处于该位置的元件(如果有),并右侧的任何后续元素(将一个元素添加到其索引中) 从中我们也发现在插入数据的时候需要把插入位置后面的数全部往后移动 所以他的插入就比较慢
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
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; // clear to let GC do its work
return oldValue;
}
然后他的插入比较慢 但是他的查询会很快 可以看:
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
我们通过看ArrayList源码发现 他基于数组的实现 因此我们的数组后续存的数据主要用于查询可以使用ArrayList 因为他的查询效率是比较高的 但是对于经常会操作数组 我们也可只 若在中间某个位置插入或者删除数据 还要移动位置 效率是比较慢的