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()));

Не могу найти ничего, чтобы поддержать или опровергнуть вышеизложенное. Я скучаю по лодке полностью здесь?

0 ответов

Другие вопросы по тегам