1.Arraylist
1.1优点与缺点:
查询效率高,增删效率低,线程不安全。使用频率很高。
无参构造函数会创建空的数组,只有真正添加元素的时候才会分配默认的10的初始容量。
有参构造函数它会按照给定的大小进行创建。
扩容机制:扩容jdk1.8以上会使用位运算,在原有的基础上右移一位,也就相当于除以2。
新增元素:新增,删除元素时都会移动元素。如果移动的元素很多,对整体的性能消耗是很大的。(复制copyOf)
查找元素:因为ArrayList集合实现了RandomAcces接口,支持快速访问(快速随机访问指的是通过元素的下标即可快速获取元素对象,无需遍历)
1.2常用方法
- boolean add(E e)
将指定的元素添加到此列表的尾部。
- void add(int index, E element)
将指定的元素插入此列表中的指定位置。
- boolean addAll(Collection c)
按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
- boolean addAll(int index, Collection c)
从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
- void clear()
移除此列表中的所有元素。
- Object clone()
返回此 ArrayList 实例的浅表副本。
- boolean contains(Object o)
如果此列表中包含指定的元素,则返回 true。
- void ensureCapacity(int minCapacity)
如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
- E get(int index)
返回此列表中指定位置上的元素。
- int indexOf(Object o)
返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
- boolean isEmpty()
如果此列表中没有元素,则返回 true
- int lastIndexOf(Object o)
返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
- E remove(int index)
移除此列表中指定位置上的元素。
- boolean remove(Object o)
移除此列表中首次出现的指定元素(如果存在)。
- protected void removeRange(int fromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
- E set(int index, E element)
用指定的元素替代此列表中指定位置上的元素。
- int size()
返回此列表中的元素数。
- Object[] toArray()
按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
- T[] toArray(T[] a)
按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
- void trimToSize()
1.3查询效率为什么快?
回答:ArrayList本身的基础数据结构,它是基于数组的数据结构,例如:我们要得到a[5],那么我们是用a[0]的地址加上4乘以每个数组元素的字节长度。
2.LinkedList
1.1优点与缺点
- LinkedList底层采用双向链表结构存储数据,允许重复数据和null值,长度没有限制。
- 优点
- 使用链表结构,不需要提前预估长度,可以克服数组需要预先知道数据长度的缺点
- 链表使用不连续的内存空间,可以充分利用计算机内存空间,实现灵活的内存动态管理
- 缺点
- 链表相比于数组会占用更多的空间,因为链表中每个节点中,除了存放元素本身,还有存放指向其他节点的指针
- 遍历和查找指定元素的速度比较慢
Node节点包含item(存储数据),next(后继节点)和prev(前继节点)。数组内存地址必须连续,而链表就没有这个限制了,Node可以分布于各个内存地址,它们之间的关系通过prev和next维护。 ```java private static class Node
{ E item; // 存储数据 Node next; // 后继节点 Node prev; // 前继节点 Node(Node
prev, E element, Node next) { this.item = element;
this.next = next;
this.prev = prev;
} }
```
- 空参构造函数,默认size为0,每次添加新元素都要创建Node节点。
1.2常用方法
add(E e)
将指定元素添加到此列表的结尾。
add(int index, E element)
在此列表中指定的位置插入指定的元素。
addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素从指定位置开始插入此列表。
addFirst(E e)
将指定元素插入此列表的开头。
addLast(E e)
将指定元素添加到此列表的结尾。
clear()
从此列表中移除所有元素。
contains(Object o)
如果此列表包含指定元素,则返回 true。
get(int index)
返回此列表中指定位置处的元素。
indexOf(Object o)
返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
offer(E e)
将指定元素添加到此列表的末尾(最后一个元素)。
peek()
获取但不移除此列表的头(第一个元素)。
poll()
获取并移除此列表的头(第一个元素)
set(int index, E element)
将此列表中指定位置的元素替换为指定的元素。
size()
返回此列表的元素数。
1.3LinkedList为甚什么删除快?
回答:LinkedList集合首先是基于双向链表的存储结构,在插入或者删除数据时,它需要调整它的前后指向就行。没有指向的关系在一段的时间会被垃圾回收。而且LinkedList在内存中是分散的存储空间,不是连续的,仅靠指向关系连接。在查数据的时候,如果数据量不大的话,查询也还可以。主要针对数量过大,遇到数据在远端的情况,它会造成性能很大的消耗。ArrayList添加删除需要用到扩容,Arrays.copyOf()和System.arraycopy()方法,而LinkedList是链表操作。