最近在查看自己写的代码的时候,发现自己在需要List数据结构的时候,都不加思考的使用ArrayList,突然莫名地想到难道Java里面就只有这一个实现类吗?带着疑问,

看了一下jdk的api:

https://docs.oracle.com/javase/7/docs/api/java/util/List.html

1. List接口的定义

public interface List<E> extends Collection<E> {
    ...;//此处省略其他方法
    E get(int index);//获取给定位置的元素
    void add(int index, E element);//向给定的位置添加元素,其他元素向后依次移位
    boolean add(E e);//在List末尾增加一个元素
    E remove(int index);//删除List中第index个元素,后面的元素的索引依次减一
    boolean remove(Object o);//删除List中第一个匹配的元素
    E set(int index, E element);//设置List中第index个元素的值
    ...;//此处省略其他方法
}

jdk的文档上面描述说List是一种有顺序的集合(有别于Set集合),使用者可以准确地控制List当中新元素被添加的位置.简单一点的说,就是链表类型.

相关元素增删改操作介绍:

  1. 插入元素: 从API的定义中我们可以了解到可以通过add(E e)和add(int index, E e)两种方法来实现,区别在于add(E e)是在末尾追加,而add(int index, E e)方法可以在List中指定的位置加入新元素(注意:索引从0开始计数);
  2. 删除元素: 从API的提供了remove(int index)和remove(Object o)两种方法,前者用来删除给定位置的元素,后者用来删除第一个匹配给定值的元素;
  3. 获取元素:List接口中提供了一个get(int index)的方法来提供给我们获取给定位置上的元素;

实现List接口的类主要有:
- AbstractList
- AbstractSequentialList
- ArrayList
- AttributeList
- CopyOnWriteArrayList
- LinkedList
- RoleList
- RoleUnresolvedList
- Stack
- Vector

这篇文章主要对LinkedList和ArrayList进行学习,其他的日后,继续补上

2. LinkedList Vs ArrayList

LinkedList和ArrayList都实现了List接口,他们的方法和执行结构基本上都是相同的,但是在某些应用场合,两者的性能差异就比较明显,下面列举了一下:

搜索: ArrayList的搜索比LinkedList快的多,ArrayList的搜索性能的算法复杂度是O(1), 而LinkedList的复杂度是O(n),主要的原因是ArrayList实现上就是使用数组,而LinkedList使用的是循环链表实现,查询的时候,ArrayList直接根据索引定位元素,而LinedList必须重头向后依次检查匹配.

删除: ArrayList的删除比LinedList相反要慢的多,主要的原因在于ArrayList需要对被删除元素后面的元素进行移位,这样的开销比较大,而LinkedList就比较简单,直接调整被删除元素前后元素的指针就行,性能的复杂度为O(1),而ArrayList的复杂度为O(n).

插入: 插入于删除基本上相同,ArrayList的复杂度为O(n),LinkedList的复杂度为O(1).

内存开销: ArrayList从本质上只需要维护元素自身的索引值和元素的值,而LinkedList不仅需要维护自身的值还需要维护两个指向相邻元素的指针,因此,从内存开销而言,LinkedList开销比ArrayList要大一些。

那么现在问题来了,该如何选用ArrayList和LinkedList呢?,主要根据两个方面来考虑:

  1. 如果场景中删除和插入操作比较多,考虑使用LinkedList,因为它的性能复杂度也就O(1);
  2. 如果场景中搜索的操作比较多,考虑使用ArrayList,因为它的性能复杂度为O(1);

看来我得好好检查自己的代码了,这些小的细节有些时候也是蛮重要的.