HashSet
жестко задан для использования hashCode()
и equals()
.Вы могли бы реализовать свой собственный HashSet
-подобный класс, возможно, безжалостно дублируя собственный исходный код Java, но это довольно уродливо, противоречит любому приличному набору правил разработки программного обеспечения и, возможно, незаконно в отношении лицензии на исходный код Java (это зависитфактический JDK, например, JDK от Sun / Oracle против OpenJDK).
Однако вы можете делать что-то с TreeSet
.TreeSet
обычно использует compareTo()
метод элементов, не hashCode()
или equals()
.Более того, экземпляр TreeSet
может быть создан с пользовательским экземпляром Comparator
, который затем вызывается для сравнения, позволяя вам иметь собственные правила.Метод compareTo()
(или метод Comparator.compare()
) должен реализовывать порядок , который может быть немного сложнее, чем простой hashCode()
-and- equals()
, но обычно это тоже не сложно.Иногда говорят, что TreeSet
медленнее, чем HashSet
, но фактическая разница незначительна, и для того, чтобы реально заметить эту разницу, требуется очень специфическая ситуация.
Концептуально, это может бытьхеш-эквивалент Comparator
для HashSet
: интерфейс HasherAndEqualizer
с методами int hashCode(Object obj)
и boolean equals(Object obj1, Object obj2)
.Sun не сочла нужным включить такой интерфейс, я не знаю почему.Возможно, они не думали, что это будет полезно.Библиотека GNU Trove, которую вы цитируете в другом ответе, предоставляет такой интерфейс.
В качестве альтернативы вы всегда можете использовать оболочки.Вместо хранения HistoryItem
экземпляров во вторичном наборе вы можете хранить HistoryItemWrapper
экземпляров, каждый из которых ссылается на фактический HistoryItem
и предоставляет методы hashCode()
/ equals()
, необходимые для этого набора.