ArrayList 和 LinkedList的区别
ArrayList
-
在内存中是连续存放的
-
根据根据指针去找对应的数据
-
查询速度快
-
插入速度慢(因为ArrayList是在内存中是连续比如我们要在1和2的中间插入数据1后面的数据都要向后移动)
-
现在我们知道了 Java 在创建数组的时候需要在内存中创建了连续的数据,那
List list = new ArrayList();
我怎么知道他的长度是多少?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. */ 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); } } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
上面的代码可以很清楚的看出来在创建的ArryList的时候可以取指定一个长度如果不指定的这个长度就是一个空的也就是0
-
假设我在创建一个ArrayList长度为16
List list = new ArrayList(16)
那么我在插入第17个元素的时候会出现什么问题?这个时候ArrayList 会进行一个 扩容
然后去计算一个长度
int newCapacity = oldCapacity + (oldCapacity >> 1);
最后进行一个数组拷贝
/** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * 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 */ 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
- LinkedList 是一个双向链表也就是说不仅前一个元素能知道后一个元素的地址,后一个元素也能知道前一个元素的地址 可以从前想后的遍历 也可以从后向前遍历
- 插入和删除速度快 查询慢(要遍历所有元素)
如上图所示 我们要在1和2之间插入1.5这个元素,只需要知道要插入元素的位置 把前一个元素的下一个指针指向新插入的元素 然后再把新插入的元素的指针 执行后面的元素地址
-
删除的话 假设我们要删除这个1.5 只需要把1.5的指针删除掉把 1的next 指针指向2 把2的prev指向1集合
-
LinkedList 是有哨兵存在的所有 让我们能知道 头和头尾