Когда Вы звоните, удаляют (возразите o) на arraylist в Java, как он сравнивает объекты найти, что корректный удаляет? это использует указатель? или это сравнивает объекты с помощью интерфейса Comparable?
ArrayList
remove()
опирается на реализацию объектов метода Equal
. Если реализация не была выполнена, то объект удаляется реализацией Object
из Equals
, которая действительно является сравнением указателя.
Из документации по ArrayList
-
Более формально удаляется элемент с наименьшим индексом i такой, что
(o==null ? get(i)==null : o.equals(get(i)))
(если такой элемент существует)
Object equal
документация к методу -
Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности на объектах; то есть для любых ненулевых ссылочных значений
x
иy
этот метод возвращает истину тогда и только тогда, когдаx
иy
ссылаются на один и тот же объект (x == y
имеет значениеtrue
).
Документы отвечают на ваш вопрос:
Удаляет один экземпляр указанного элемента из этой коллекции, если он присутствует (необязательная операция). Более формально, удаляет элемент
e
такой, что(o==null ? e==null : o.equals(e))
, если коллекция содержит один или несколько таких элементов.
Используется equals()
из docs:
Удаляет первое вхождение указанного элемента из этого списка, если он присутствует. Если список не содержит элемента, он остается неизменным. Более формально, удаляет элемент с наименьшим индексом i такой, что (o==null ? get(i)==null : o.equals(get(i))) (если такой элемент существует). Возвращает true, если данный список содержал указанный элемент (или эквивалентно, если данный список изменился в результате вызова).
Для получения такой информации всегда следует обращаться к API.
ArrayList.remove (Object o)
: Удаляет первое вхождение указанного элемента из этого списка, если он присутствует. Если в списке нет элемента, он остается неизменным. Более формально удаляет элемент с наименьшим индексомi
, так что(o == null? Get (i) == null: o.equals (get (i)))
( если такой элемент существует).
Возможно, вы путали это, например, с TreeSet
:
java.util.TreeSet
: обратите внимание, что порядок, поддерживаемый набором (независимо от того, предоставлен ли явный компаратор), должен согласовываться с равным , если это правильно реализовать интерфейсSet
. (См. Comparable или Comparator для точного определения соответствия с равными.) Это так, потому что интерфейсSet
определен в терминах операцииравно
, но экземплярTreeSet
выполняет все сравнения элементов, используя егоcompareTo
(илисравнить
), поэтому два элемента, которые считаются равными с помощью этого метода, с точки зрения набора равны.
(К сожалению, например, сам метод TreeSet.remove
не имеет явного напоминания о вышеупомянутом предостережении, но, по крайней мере, он заметно помещен в верхней части документации класса)
Следующий фрагмент демонстрирует разницу в поведении между коллекциями, в которых используется равно
(например, 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
}
}