Когда вы вызываете remove (объект o) для массива, как он сравнивает объекты? - PullRequest
27 голосов
/ 24 мая 2010

Когда вы вызываете remove (объект o) для массива в Java, как он сравнивает объекты, чтобы найти правильный для удаления? он использует указатель? или сравнивает объекты используя интерфейс Comparable?

Ответы [ 4 ]

17 голосов
/ 24 мая 2010

ArrayList remove() опирается на реализацию объектов метода Equal. Если реализация не была выполнена, то объект удаляется реализацией Object Equals, которая действительно является сравнением указателя.

Из документации на ArrayList -

Более формально, удаляет элемент с наименьшим индексом i таким, что (o==null ? get(i)==null : o.equals(get(i))) (если такой элемент существует)

Объект equal документация по методу -

Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности на объектах; то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true, если и только если x и y ссылаются на один и тот же объект (x == y имеет значение true).

8 голосов
/ 24 мая 2010

Вы должны всегда консультироваться с API для получения такой информации.

ArrayList.remove(Object o): Удаляет первое вхождение указанного элемента из этого списка, если он присутствует. Если список не содержит элемент, он не изменяется. Более формально, удаляет элемент с самым низким индексом i таким, что (o==null ? get(i)==null : o.equals(get(i))) (если такой элемент существует).

Возможно, вы путали это, например, с TreeSet

java.util.TreeSet: обратите внимание, что порядок, поддерживаемый набором (независимо от того, предоставляется ли явный компаратор), должен быть в соответствии с равным , если он предназначен для правильной реализации Set интерфейс. (См. Comparable или Comparator для точного определения соответствия с equals.) Это так, потому что интерфейс Set определен в терминах операции equals, но экземпляр TreeSet выполняет все сравнения элементов, используя compareTo (или compare), поэтому два элемента, которые считаются равными этим методом, с точки зрения набора равны.

(К сожалению, например, TreeSet.remove сам метод не имеет явного напоминания о приведенном выше предупреждении, но, по крайней мере, он занимает видное место вверху документации класса)


Наглядный пример

Следующий фрагмент иллюстрирует различие в поведении между коллекциями, использующими equals (например, ArrayList), и коллекциями, использующими compare/compareTo (например, TreeSet).

import java.util.*;

public class CollectionEqualsCompareTo {
    static void test(Collection<Object> col, Object o) {
        col.clear();
        col.add(o);
        System.out.printf("%b %b %b %b%n",
            col.contains(o),
            col.remove(o),
            col.contains(o),
            col.isEmpty()
        );
    }
    public static void main(String[] args) {
        Object broken1 = new Comparable<Object>() {
            // Contract violations!!! Only used for illustration!
            @Override public boolean equals(Object o)    { return true; }
            @Override public int compareTo(Object other) { return -1;   }
        };
        Object broken2 = new Comparable<Object>() {
            // Contract violations!!! Only used for illustration!
            @Override public boolean equals(Object o)    { return false; }
            @Override public int compareTo(Object other) { return 0;     }
        };
        test(new ArrayList<Object>(), broken1); // true true false true
        test(new TreeSet<Object>(),   broken1); // false false false false
        test(new ArrayList<Object>(), broken2); // false false false false
        test(new TreeSet<Object>(),   broken2); // true true false true
    }
}
1 голос
/ 24 мая 2010

Используется equals()

из документов :

Удаляет первое вхождение указанного элемента из этого списка, если он присутствует. Если список не содержит элемент, он не изменяется. Более формально, удаляет элемент с наименьшим индексом i таким образом, что (o == null? Get (i) == null: o.equals (get (i))) (если такой элемент существует). Возвращает true, если этот список содержал указанный элемент (или эквивалентно, если этот список изменился в результате вызова).

1 голос
/ 24 мая 2010

документы ответят на ваш вопрос:

Удаляет один экземпляр указанный элемент из этого сбор, если он присутствует (необязательно операция). Более формально, удаляет элемент e такой, что (o==null ? e==null : o.equals(e)), если коллекция содержит один или несколько таких элементов.

...