我们说链表不是基于索引的集合,为什么?

时间:2014-07-19 12:41:09

标签: data-structures arraylist linked-list

我无法弄清楚linkedlist和arraylist之间的区别。以下实现让我更加困惑。 Uptil现在我假设LinkedList不是基于索引的数据结构。

package com.rnd.core.collections;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class LinkedListTest {
    public static void main(String[] args) {
        List<String> myLinkedList = new LinkedList<String>();
        myLinkedList.add("Spring");
        myLinkedList.add("Struts");
        myLinkedList.add("EJB");
        myLinkedList.add("Hibernate");
        myLinkedList.add(1, "Collections");
        myLinkedList.add(1, "JMS");

        System.out.println(""+myLinkedList.subList(1, 3));
        System.out.println("Search result for \"Hibernate\":" + myLinkedList.contains("Hibernate"));
        System.out.println("Search result for \"Hibernate\":" + myLinkedList.contains("ibatis"));
        for(String item: myLinkedList){
            System.out.println(item.toString());    
        }

        System.out.println("<><>"+myLinkedList.get(1));

        List<String> myArrayList = new ArrayList<String>();

        myArrayList.add("Spring");
        myArrayList.add("Struts");
        myArrayList.add("EJB");
        myArrayList.add("Hibernate");
        myArrayList.add(1, "Collections");
        myArrayList.add(1, "JMS");

        myArrayList.subList(1, 2);
        System.out.println("*****************"+myArrayList.subList(1, 3));

    }

}

在这方面,我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

区别在于底层实施。数组是固定大小的内存块,分为块,每个块包含一个元素。使用索引号很容易跳转到任何单个元素,修改一个元素不会影响数组的其余部分。向元素添加元素是很昂贵的,因为您基本上需要将整个数组复制到更大的空间中,以便为新元素腾出空间。 (通过预分配比实际需要更多的空间,可以更快地添加到数组的末尾,但最终您需要再次复制整个数组。)

另一方面,链表由独立的内存块组成,每个内存块包含要存储的元素和指向列表中下一个项的指针。添加到这样的列表(给定指向要添加的位置的指针)很快,因为您只需要获取新的内存块并修改少量节点的指针,而与列表的大小无关作为一个整体。成本是为了获取指向中间任意节点的指针,你需要从头开始遍历列表的长度。

这有点简化,但主要思想是每个底层数据类型都适用于“列表”抽象概念的不同应用程序,您需要考虑操作类型(查找,添加,删除等等,在选择哪个更合适之前要执行。