Имеет ли смысл быть равным и сравнивать, чтобы быть непоследовательным? - PullRequest
7 голосов
/ 27 апреля 2009

Я хочу сделать класс пригодным для использования в SortedSet | SortedMap.

class MyClass implements Comparable<MyClass>{
  // the only thing relevant to comparisons:
  private final String name;

  //...
}

Экземпляры класса должны быть отсортированы по свойству name.
Однако я не хочу, чтобы экземпляры с одинаковыми именами считались равными.

Таким образом, содержимое SortedSet будет выглядеть так: a, a, a, b, c .
(Обычно SortedSet допускает только a, b, c )

Прежде всего: это (философски) непротиворечиво?

Если так, то должен ли я ожидать непредсказуемого поведения, когда я не переопределить equals(...) и hashCode()?

Edit:
Извините, мой вопрос кажется противоречивым:
Я хочу поместить несколько "равных" значений в set , что не позволяет по концепции.
Поэтому, пожалуйста, больше не отвечайте на мой вопрос.
Спасибо всем, кто уже ответил.

Ответы [ 4 ]

18 голосов
/ 27 апреля 2009

Позвольте мне задать вам вопрос: имеет ли смысл иметь a.compareTo(b) return 0 и a.equals(b) return false?

Я бы использовал Comparator<MyClass>. Вот почему все SortedMap / SortedSet реализации, которые я знаю, позволяют вам передавать Comparator при создании.

4 голосов
/ 27 апреля 2009

Из Javadoc для сопоставимых

Настоятельно рекомендуется (хотя и не требуется), чтобы естественные заказы были в соответствии с равными. Это так потому что отсортированные наборы (и отсортированные карты) без явных компараторов ведут себя « странно », когда они используются с элементы (или ключи), чьи естественные порядок не соответствует равным

Если вы хотите, чтобы CompareTo несовместимо с equals (), рекомендуется вместо этого использовать явный компаратор, предоставив класс, реализующий Comparator.

Если это так, то следует ли ожидать непредсказуемого поведения, когда я не переопределяю equals (...) и hashcode ()?

Вы все равно должны переопределить equals () и hashcode (). Согласовано ли equals () и hashcode () с CompareTo - это другой вопрос.

2 голосов
/ 27 апреля 2009

Effective Java рекомендует, чтобы, если вы не внедрили compareTo в соответствии с equals, вы должны четко указать следующее:

Рекомендуемый язык: «Примечание: Этот класс имеет естественный порядок, несовместимо с равными. "

0 голосов
/ 27 апреля 2009

Просто поместите этот код в метод equals и больше никогда не думайте об этом:

public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof MyClass)) return false;
    return 0 == this.compareTo((MyClass) obj);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...