2013-03-16 2 views
2

В Java интерфейс Comparator позволяет клиенту указывать метод equals() и compare() для любого типа. Компаратор может быть передан большинству (или, возможно, всем) наборам, которые требуют сортировки, а методы в Компараторе будут использоваться вместо методов указанного класса. Это позволяет клиентам сортировать объекты таким образом, который отличается от их естественного упорядочения или даже сортировать объекты, которые не имеют естественного упорядочения (т. Е. Не реализуют Comparable).Почему Java не имеет интерфейса, подобного Компаратору, но для хэширования?

Почему нет подобного интерфейса для хеширования? Он может указывать два метода: hashCode() и equals() и быть полезными для HashSets или HashMaps таким же образом, чтобы компараторы были полезны для сортировки.

Редактировать: Для тех, кто отметил этот вопрос, дубликат this other question, я бы сказал, что в другом вопросе спрашивается, почему hashCode включен в каждый класс вместо интерфейса, в то время как этот вопрос касается абстрагирования хеширующей функции, позволяющей использовать несколько реализаций из этого.

Ответ Edit: Лучшие методы получения этой функции кажутся:

-Если ты в порядке, используя внешнюю библиотеку и/или уже используют Guava (который является фантастическая библиотека для целого ряда причин), Guava имеет класс Equivalence, который позволяет это.

-Если вы не хотите использовать внешнюю библиотеку, вы можете использовать настраиваемый адаптер, аналогичный тому, что сделано в верхнем ответе на this SO question.

+2

Ознакомьтесь с http://stackoverflow.com/questions/15094818/compare-two-java-collections-using-comparator-instead-of-equals – sharakan

+0

'equals()' и 'hashCode()' определены в Класс 'Object', поэтому ** каждый ** класс уже имеет их –

+2

Во-первых,' hashCode' является встроенной версией из 'Object'. Это означает, что он всегда будет определен в любом классе. 'equals' также определяется в Object. Оба они всегда будут определены в любом случае, поэтому иметь интерфейс для них не имеет смысла. – 2013-03-16 23:00:36

ответ

4

Вопросы формы

"Почему не Java есть XXX"

трудно ответить объективно, кроме как с общим

«Мы не знаем, потому что никто не был в комнате, когда было принято решение ».

В этом случае:

  • На первый взгляд, это требование может быть реализовано ... с технической точки зрения.

  • Это требование было предложено много раз через радиопомехи. Самый прямой - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6435963. RFE отмечен как WONT FIX, хотя особых причин нет.

  • Это требование может быть выполнено и было должным образом удовлетворено сторонними библиотеками.

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

+0

Я согласен со всем в вашем ответе от анализа вопроса до вашего чтения. Я в основном задавался вопросом, есть ли причина, кроме того, что во многих случаях это не будет полезно. Также спасибо за ссылку на соответствующую RFE. – Mark

+0

* «Меня в основном интересовало, есть ли причина, кроме того, что во многих случаях это было бы бесполезно». * - Это просто наблюдаемый факт. В подавляющем большинстве случаев «естественный» эквивалент и хэш-код ключевого объекта в порядке. Зачем? Может быть, потому что люди не используют «фанковые ключи»? Или потому, что если они используют «funky keys», то они используют TreeMaps, а не HashMaps? –

+0

В старые добрые времена вы могли бы получить приблизительную оценку того, сколько поддержки RFE было основано на количестве голосов, полученных в Паралле ошибок. К сожалению, Oracle решила, что они больше не хотят знать. –

0

Хешинг действительно имеет только одно требование: Быть подобно хеш-методу. Таким образом, вы можете реализовать его для типа, не зная, кто будет его использовать каким образом и с какой целью. Поэтому достаточно хэш-метода для самого объекта.

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

Конечно ничто не мешает вам создать такой интерфейс и использовать его ...

+1

Методы 'hashCode()' и 'equals()' неразрывно связаны.Если тип имеет несколько разумных значений для 'equals()', он, как правило, имеет столько же разумных значений для 'hashCode()'. Возможно, будет реализована реализация 'hashCode()', которая будет работать приемлемо для нескольких методов 'equals' [например. как чувствительные к регистру, так и нечувствительные к регистру сравнения могут использовать хеш-значение, вычисленное из версии строки только в верхнем регистре], но такие методы, как правило, не будут оптимальными. – supercat

0

Вы всегда можете изменить хэш-код(), чтобы сказать, как HashMap организует ваш объект в карте и улучшить его Performence путем внедрения эффективной hashcode в вашем классе.

Как HashMap выполняет добавление и удаление из данных хэшированном является внутренним HashMap и изменить это будет означать изменение в основном добавлять, удалять методы и т.д.

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

1

Я также считаю, что такой интерфейс был бы удобен, в частности, как способ рассмотреть различные типы равенств в коллекциях. Он должен быть аналогичен тому, как вы можете сделать объект Comparable, но все же переопределите это поведение в конкретной коллекции, предоставив некоторые другие Comparator.

Как было указано в this question, у Guava есть класс Equivalence, который предоставляет способ сделать это, обертывая ваш класс и позволяя вам определить на уровне обертки, что означает «равенство» в этом контексте.

Если ваш вопрос действительно, почему этого не произошло во время разработки языка ...ну, эй, James Gosling и компания только люди, не так ли?

0

Позвольте мне попытаться сказать, как я его вижу, почему.

Кратко - часто нужно рода список объектов, но редко (если вообще) нужно пересечь сравнить тождества из списка объекта.


В Object, метод хэш-код является вторичным, полезный метод, основной целью которого является служить равно метод. Соглашение заключается в том, что если для двух объектов hashCode возвращает разные значения, равно не должен возвращать true.

Таким образом, методы HashCode и равна служат для установления идентичности объекта.

Метод compareTo (как в сравнении, так и в компараторе) служит другим общим назначением. Он определяет объектов заказа, а не их identity.

Резюме - CompareTo определяет, как объектов являются заказанными, HashCode (вместе с равно) определяют объектов удостоверения.


Опять же - практика вклад является то, что вам часто приходится сортировать группу объектов, но редко (если вообще) должны взять группу объектов и кросс сравнить их тождества.

Смежные вопросы