我有两个始终具有相同大小的LinkedList对象。我想比较它们,看看它们的内容是否相同。为每个列表创建ListIterator并使用while hasNext循环与使用计数器(int i)并使用linkedlist.get(i)从0迭代到linkedlist.size()来获取和比较的一般性能和样式含义是什么?价值?有没有更好的方式让我俯视?
我唯一能想到的是ListIterator方法可能更好,因为我以后可以更容易地交换另一个Comparable列表(而不是我计划它)。我不知道两者在引擎盖下是什么样子,所以我不确定如何比较它们的性能。
答案 0 :(得分:7)
事实证明AbstractList.equals()
(LinkedList
使用)会自动执行此操作,因此请使用它。代码是:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1 == null ? o2 == null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
所以不要重新发明轮子。
最后一点:不要使用get(index)
来迭代LinkedList
。这是O(n)访问(ArrayList
的O(1))所以使用LinkedList
的{{1}}遍历将是O(n 2 )。
答案 1 :(得分:5)
对LinkedList
的随机访问具有可怕的性能(它需要从一端开始并重复调用next
或类似内容),因此ListIterator
会更快。
答案 2 :(得分:1)
get(n)
对于扩展AbstractSequentialList
的类不是常量操作;它是O(n)
。来自AbstractSequentialList#get(int index):
此实现首先获取指向索引元素的列表迭代器(使用
listIterator(index)
)。然后,它使用ListIterator.next
获取元素并返回它。
通常,您不希望对未实现标记接口java.util.RandomAccess
的集合执行随机访问。
根据经验,对于典型的类实例,如果这个循环,List实现应该实现此接口:
for (int i=0, n=list.size(); i < n; i++) list.get(i);
比这个循环运行得更快:
for (Iterator i=list.iterator(); i.hasNext(); ) i.next();
从Java SE 6开始,实现类为ArrayList, AttributeList, CopyOnWriteArrayList, RoleList, RoleUnresolvedList, Stack, Vector
。