Java: Как обойти отсутствие Equatable интерфейса? - PullRequest
3 голосов
/ 18 июня 2010

Насколько я знаю, такие вещи, как SortedMap или SortedSet, используют compareTo (а не equals) на Comparable<?> типах для проверки равенства (contains, containsKey).

Но что, если определенные типы сопоставимы по концепции, но не сопоставимы?
(хэш-коды, адреса памяти, ...)

Я должен объявить Comparator<?> и переопределить метод int compareTo(T o1, To2). ОК, я могу вернуть 0 для экземпляров, которые считаются равными. Но, для необычных случаев, что я возвращаю, когда заказ не очевиден?

Является ли подход использования SortedMap или SortedSet на равным , но (по концепции) несопоставимых типов в любом случае хорош?

Спасибо!

EDIT:
Я не хочу хранить отсортированные вещи, но если бы я использовал «обычные» Map и Set, я бы не смог «переопределить» поведение равенства.

РЕДАКТИРОВАТЬ 2:
Почему я не могу просто переопределить equals(...):
Мне нужно изменить поведение равенства иностранного класса. Я не могу его редактировать.

РЕДАКТИРОВАТЬ 3:
Подумайте только о .NET: у них есть интерфейс IEquatable, который может изменять поведение равенства, не затрагивая сопоставимое поведение.

РЕДАКТИРОВАТЬ 4:
Разве я не могу просто заставить compareTo вернуть 0 для равных и 1 для неравных экземпляров? В чем большая проблема? У меня есть несколько тестов, кажется, что SortedMap / SortedSet вызывают CompareTo для пары экземпляров один раз. Да, порядок не имеет смысла, но почему это должно быть моей проблемой? Мне не нужен заказ. * Мне просто нужно изменить поведение равенства. К сожалению, большинство людей просто не могут этого понять.
ПРИМЕЧАНИЕ: Концепция возврата 1 для неравных случаев теперь оказалась неверной.

РЕДАКТИРОВАТЬ 5:
Изменение поведения равенства иностранных классов - это плохая концепция? Конечно? Я так не думаю: почему тогда мне разрешено изменять поведение сравнения иностранных классов , используя Comparator?

РЕДАКТИРОВАТЬ 6:
Спасибо Mark Peters и waxwing за идею обертывания типа ключа в пользовательский класс. Таким образом, я могу переопределить equals и hashCode, тем самым изменив поведение равенства.

Ответы [ 13 ]

0 голосов
/ 18 июня 2010

Просто используйте (пользовательский) компаратор, предоставленный для реализации Sorted [Set | Map], при его создании ...

Javadocs склонен предлагать это: All keys inserted into a sorted map must implement the Comparable interface (or be accepted by the specified comparator).

SortedSet<MyObject> s = new TreeSet<MyObject>(new Comparator<MyObject>() {
    @Override
    public int compare(T o1, T o2) {
        // your very specific, fancy dancy code here
    }
});

http://java.sun.com/javase/6/docs/api/

0 голосов
/ 18 июня 2010

Как уже говорили другие, если нет естественного порядка, SortedXXX на самом деле не вариант.Однако, если вы просто хотите какой-то последовательный способ перечисления элементов, если вы просто учитываете поля, которые вы используете для проверки на равенство, так как они составляют «первичный ключ», и придумаете какой-то числовой или алфавитный порядоквокруг них, которые могут соответствовать вашим целям.

0 голосов
/ 18 июня 2010

Вы не можете сортировать объекты, если они не сравнимы;как бы вы узнали, какой из двух объектов должен стоять первым, если они несопоставимы?Таким образом, нет никакого способа поместить объекты, которые не сопоставимы в SortedMap или SortedSet.(Почему вы хотите? Используйте другой тип Map или Set).

Метод equals() в Java определен в классе Object, и поскольку все классы расширяются Objectвсе объекты имеют метод equals().Вы должны позаботиться о том, чтобы правильно переопределить и реализовать equals() в своих классах, если хотите иметь возможность определить, равны ли два объекта.

Если вы хотите поместить объекты в коллекцию на основе хешанапример, HashMap или HashSet), вы также должны переопределить hashCode(), и вы должны убедиться, что hashCode() и equals() реализованы правильно (подробности см. в документации этих методов в классе Object).как это сделать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...