Пусть следующий API:
final class Foo {
int bar;
Foo(int bar) { this.bar = bar; }
public int hashCode() {
return bar;
}
public boolean equals(Object o) {
return o instanceof Foo && ((Foo)o).bar == bar;
}
}
static Set<Foo> getSetOpaquely() {???}
Я не знаю, где набор приходит, только что мне нужно, чтобы использовать его.
Предположим, что набор выполнен как HashSet и определен в терминах equals
.
Они также дают пример «странного» поведения, когда (a.equals(b) && c.compare(a,b) != 0)
Пусть я
Set<Foo> mySet = getSetOpaquely();
mySet.add(new Foo(1));
System.out.println(mySet.add(new Foo(1));
Пусть мое удивление, когда печатается true
, потому что это был TreeSet с компаратором
(lhs, rhs) -> lhs == rhs ? 0 : 1
Теперь, может ли кто-нибудь дать мне пример «странного» поведения в случае (!a.equals(b) && c.compare(a,b) == 0)
?
Пусть я
Set<Foo> mySet = getSetOpaquely();
mySet.add(new Foo(102));
System.out.println(mySet.add(new Foo(12));
Пусть мое удивление, когда печатается false
, потому что это был TreeSet с компаратором
(lhs, rhs) -> Integer.compare(lhs.bar % 10, rhs.bar % 10)
Теперь, не существует врожденная проблема с определяющим порядком, который не соответствует equals
.Дело в том, что TreeSet может вести себя иначе, чем указано в документации для Set.
Это clearly documented:
[...] интерфейс Set
определен в терминах операции равна, но TreeSet
экземпляр выполняет все сравнения элементов, используя свой метод compareTo
(или compare
), так что два элементы, которые по этому методу считаются равными, равны, с точки зрения множества. Поведение набора четко определено, даже если его порядок не согласуется с равными; он просто не подчиняется генеральному контракту интерфейса Set
.
Пока компаратор не Hacky, и вы знаете, что это TreeSet с конкретным заказом, вы не будете удивлены. (Если это взломано, как (lhs, rhs) -> 1
, вы можете быть удивлены.)
Если вы читаете документацию для 'Set', в ней говорится, что если у вас есть два одинаковых объекта, то в наборе сохраняется только один (или ни один) из них. Это неверно, если это TreeSet с использованием компаратора, который не согласуется с равными. – immibis