Сравнение двух LinkedList с ListIterator против for loop и get (индекс int)
У меня есть два объекта LinkedList, которые всегда имеют одинаковый размер. Я хочу сравнить их, чтобы увидеть, если они идентичны по содержанию. Каковы общие последствия для производительности и стиля создания Листератора для каждого списка и использования цикла while hasNext по сравнению с использованием счетчика (int i) и итерации от 0 до linkedlist.размер () с помощью linkedlist.получить (i), чтобы получить и сравнить значения? Есть ли лучший способ, который я упускаю из виду?
единственное, что я могу думать, что метод ListIterator может быть лучше в том, что я мог бы легче поменять в другом сопоставимом списке позже (не то, что я планирую на него). Я не знаю, как они выглядят под капотом, поэтому я не уверен,как бы я сравнил их с производительностью.
3 ответов
как выяснилось AbstractList.equals()
(где LinkedList
uses) сделает это автоматически, поэтому используйте это. Код:
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) доступ(O (1) для ArrayList
) так LinkedList
обход с помощью get(index)
будет O (n2).
случайный доступ в LinkedList
имеет ужасную производительность (она должна начинаться с одного конца и вызывать next
или подобное неоднократно), поэтому ListIterator
будет быстрее.
get(n)
для связанных списков не является постоянной операцией для классов, которые расширяются AbstractSequentialList
, это O(n)
. От AbstractSequentialList#get (int index):
эта реализация сначала получает итератор списка, указывающий на индексированный элемент (с
listIterator(index)
). Затем он получает элемент, используяListIterator.next
и возвращает его.
как правило, вы не хотите делать случайный доступ к коллекциям, которые не реализуют интерфейс маркера java.util.RandomAccess
.
как правило, реализация списка должна реализовать этот интерфейс, если для типичных экземпляров класса этот цикл:
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
.