ConcurrentSkipListSet полагается на свой компаратор для обеспечения уникальности?
По-видимому, Java ConcurrentSkipListSet
полагается на предоставленный компаратор, чтобы определить, есть ли уже элемент в списке. Это, конечно, выглядит для меня как ошибка, но, возможно, это особенность? Если так, то это, конечно, не очень интуитивный, так как я ожидаю ConcurrentSkipListSet
все еще вести себя как нормальный Set
и уважение equals()
результат. Вот самый короткий пример, который я мог бы придумать:
static class Item {
String id;
int value;
Item(String id, int value) {
this.id = id;
this.value = value;
}
@Override
public boolean equals(Object obj) {
return Objects.equals(id, ((Item)obj).id)
&& Objects.equals(value, ((Item)obj).value);
}
@Override
public int hashCode() {
return Objects.hash(id, value);
}
@Override
public String toString() {
return String.format("id=%s, value=%s", id, value);
}
public static void main(String[] args) {
ConcurrentSkipListSet<Item> list =
new ConcurrentSkipListSet<>(Comparator.comparing(e -> e.value));
Item item1 = new Item("Item1", 3);
Item item2 = new Item("Item2", 3);
System.out.println("item1.equals(item2) -> " + item1.equals(item2));
list.add(item1);
list.add(item2);
list.forEach(e -> System.out.println(e));
}
Выход:
item1.equals(item2) -> false
id=Item1, value=3
Мне удалось заставить вышеупомянутую работу работать как ожидалось (по крайней мере, насколько мои ожидания идут), добавив Guava's Ordering.arbitrary()
компаратору прервать упорядочивание связей, например:
ConcurrentSkipListSet<Item> list =
new ConcurrentSkipListSet<>(Comparator
.comparing(e -> e.value)
.thenComparing(Ordering.arbitrary()));
Не могу найти ничего, чтобы поддержать или опровергнуть вышеизложенное. Я скучаю по лодке полностью здесь?