Java中的LinkedList更新性能

时间:2016-06-23 00:56:46

标签: java linked-list

在下面这段代码中,我发现总是删除第一个listnode并且打印第一个节点比保持列表完整并迭代所有节点更有效(就执行时间而言)。我想知道这是因为当我总是删除第一个节点时,我只需要将起始节点更新到下一个节点,然后只需获取第一个节点来打印该值。如果通过保持列表intanct迭代整个列表,则get操作每次遍历列表到指定的索引并获取值。 现在我的问题是: 1)我的理解是否正确? 2)两种方式都应该同时执行 3)还有其他推理吗?

public class Ddbrw {
public List<Integer> ListValidation()
    {
        List<Integer> lst = new LinkedList<>();
        for(int i = 0; i < 20; i++ ){
        lst.add(new Integer(1)); lst.add(new Integer(5));
        lst.add(new Integer(9)); lst.add(new Integer(7));
        lst.add(new Integer(5)); lst.add(new Integer(61));
        lst.add(new Integer(8)); lst.add(new Integer(12));
        }
        return lst;
    }

public static void main(String[] args) 
   {
    Ddbrw obj = new Ddbrw();
    Ddbrw obj2 = new Ddbrw();

    List<Integer> lst = obj2.ListValidation();
    int size = lst.size();
    long startTime = System.currentTimeMillis();
    for(int i = 0; i < size; i++) {
        System.out.print(lst.get(i));
    }
    long endTime = System.currentTimeMillis();
    System.out.println("*************");
    System.out.println(endTime-startTime);
    System.out.println("*************");

    List<Integer> lst2 = obj.ListValidation();
    long startTime1 = System.currentTimeMillis();
    for(int k = 0; k < lst2.size(); ) {
        System.out.print(lst2.get(k));
        lst2.remove(k);
    }
    long endTime1 = System.currentTimeMillis();
    System.out.println("*************");
    System.out.println(endTime1-startTime1);
    System.out.println("*************");
    }
}

2 个答案:

答案 0 :(得分:1)

您的初步推理是正确的,重点是LinkedList并不意味着随机访问效率很高。因此,每次按索引访问元素时(例如lst.get(k)),您都必须从列表的开头到达该元素。

但这并不意味着LinkedList无法在您的情况下有效使用,只是您尝试将其用作ArrayListList<T>提供Iterator<T>,在迭代列表时效率更高。

例如:

Iterator<Integer> it = lst.iterator();

while (it.hasNext())
  System.out.println(it.next());

for (int i : lst)
  System.out.println(i);

这将迭代列表而不必在每次迭代时到达k个元素,因为它跟踪迭代器内的所有内容。

实际上,在某些情况下,这可能比ArrayList更有效,因为每次删除元素时都不必记忆/移动连续的元素。

答案 1 :(得分:0)

您的观察结果与链接列表有关,只是因为您正在按索引遍历。 Java有一个RandomAccess接口,用于标识可以在固定时间内编制索引的List实现,例如由ArrayList实现,但不是由LinkedList实现。

如果您使用迭代器来遍历列表,那么您将获得大致相同的性能:

for (Integer i : lst) {
    System.out.println(i);
}