ArrayList和LinkedList

Posted JohnEricCheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList和LinkedList相关的知识,希望对你有一定的参考价值。

List ADT(抽象数据类型)有两种流行的实现方式。

ArrayList:

  提供了List ADT的一种可增长数组的实现。使用ArrayList的优点在于,对get和set的调用花费常数时间。其缺点是新项的插入和现有相的删除代价昂贵,除非变动的是在ArrayList的末端。看下面代码,add和remove方法,当指定位置添加或者删除一个元素的时候,指定位置以及之后的元素都会后移或者前移。

 1 public interface List<AnyTipe> extends Collection<AnyTipe> {
 2   AnyType get(int idx);
 3   AnyType  set(int idx, AnyType  newVal);
 4 
 5    //在指定下标插入元素,原位置以及之后的元素全部后移
 6   void add(int idx, AnyType x);
 7 
 8   void remove(int idx);
 9 
10   ListIterator<AnyType> listIterator( int pos);
11 }

  

LinkedList:

  提供了List ADT的双链表实现。使用LinkedList的优点在于,新项的插入和现有项的删除均开销很小,假设变动项的位置是已知的。意味着在表的前端进行插入和删除是常数时间的。LinkedList的缺点是不容易操作索引,因此对get的调用是昂贵的,除非调用非常近的端点。

eg:remove方法对LinkedList类的使用:

题目:将一个表中所有具有偶数值的项删除

想法:

  1、构造一个包含所有奇数的新表,然后清除原表,并将这些奇数拷贝回原表。

  2、直接在原表上操作,遍历原表,发现奇数项,直接将其删除

问题:

  ArrayList插入删除花费昂贵,显然是一个比较失败的策略。LinkedList却是存在着某种希望,因为我们知道,在已知位置的删除操作都可以通过重新安排某些链而被有效的完成。

解法:

  

 1   /**
 2      * 这种方式产生的问题:
 3      *  1、LinkedList中的get方法,调用的效率不高
 4      *  2、remove方法调用的Collection接口的方法,效率低下
 5      * @param list
 6      */
 7     public static void  removeVal1(List<Integer> list) {
 8         int i = 0;
 9         while(i < list.size()) {
10             if(list.get(i) % 2 == 0) {
11                 list.remove(i);
12             }else {
13                 i++;
14             }
15         }
16     }
 1  /**
 2      * 1、使用迭代器一步步的遍历该表,取代get,这样做是高效的。
 3      * 2、但是我们使用的是Collection接口的remove方法,这么做不是高效的,因为remove方法必须再次搜索该项。
 4      * 3、运行程序回发现一个问题:java.util.ConcurrentModificationException
 5      *      当一项被删除时,由于增强的for循环使用的基础迭代是非法的。
 6      *      我们不能期待增强for循环懂得只有当一项不被删除时,他才必须向前推进。
 7      *
 8      * @param list
 9      */
10     public static void  removeVal2(List<Integer> list) {
11         for(Integer item : list) {
12             if(item % 2 == 0) {
13                 list.remove(item);
14             }
15         }
16     }
/**
     * 迭代器的remove方法花费常数的时间,因为该迭代器位于需要被删除的节点位置。
     * @param list
     */
    public static void  removeVal3(List<Integer> list) {
        Iterator<Integer> itra = list.iterator();
        while(itra.hasNext()) {
            Integer item = itra.next();
            if(item % 2 == 0) {
                itra.remove();
            }
        }
    }

 

以上是关于ArrayList和LinkedList的主要内容,如果未能解决你的问题,请参考以下文章

从源代码来理解ArrayList和LinkedList差别

ArrayList和LinkedList介绍

ArrayList和LinkedList

ArrayList和LinkedList循环遍历效率探索

ArrayList vs LinkedList Java [重复]

优雅代码13-linkedList插入真的比arrayList快么