ключи хэш-карты Java - PullRequest
       37

ключи хэш-карты Java

0 голосов
/ 14 марта 2011

Есть ли причина, по которой вы бы использовали что-то кроме String в качестве ключа хеш-карты?Кажется, что струны достаточно хороши в 99% случаев.Кроме того, вам не нужно реализовывать hashCode () и equals (Object o).Спасибо

Ответы [ 7 ]

1 голос
/ 14 марта 2011

Строки могут охватывать множество вариантов использования, но использование более сложных объектов может дать вам гораздо большую гибкость в вашем коде. Видя, что в США только что объявили семена баскетбольного турнира NCAA, я посмотрю, смогу ли я привести пример с турнирной темой.

Предположим, я хочу создать Hashmap, в котором хранятся все команды, которые есть в каждом регионе. В турнире четыре региона: восток, запад, юго-запад и юго-восток. Вы, безусловно, можете создать свою карту как:

HashMap<String, List<Team>> teamsInRegions = new HashMap<String, List<Team>>();

Но тогда, что если у вас уже есть объект, представляющий регион? Скорее всего, так будет, поскольку с каждым регионом связано гораздо больше информации, чем с именем. Например, я считаю, что класс Region может выглядеть следующим образом:

public class Region {
    private String name;

    private Calendar firstRound;
    private String firstRoundLocation;

    private Calendar secondRound;
    private String secondRoundLocation;

    private Calendar thirdRound;
    private String thirdRoundLocation;

    ....
}

Вы поняли идею. Если бы HashMap был основан на String, вы наверняка могли бы избежать использования разумного метода Region.toString () и использовать его в качестве ключа, но использование более сложного объекта позволит вам писать более гибкий код.

В то время как другие могут не соглашаться, я иногда использую Карты несколько непредсказуемым образом, где вызов HashMap.keySet () дает мне Набор полностью заполненных, сложных объектов с множеством информации. И наличие карты означает, что я могу использовать эти объекты для принятия решений и в других местах.

Например, предположим, я хотел составить список всех мест всех игр в баскетбольном турнире. Если бы у меня был HashMap со сложными объектами, это было бы так просто:

Set<Region> regions = myMap.keyset();
Set<String> gameLocations = new HashSet();
for (Region region : regions) {
    gameLocations.add(region.getAllLocales());
}

И так далее. YMMV.

1 голос
/ 14 марта 2011

Иногда вам нужен объект вместо строки

Предположим, что у вас есть карта ... скажем, карта (словарь или другие хэш-таблицы) клиентов и заказов в ресторане.

Вместо того, чтобы

Customer c = new Customer("Bob");
Order o = new Order("Fries");
HashMap<string, Order> map = new HashMap<string, Order>();
map.put(c.Name, o);

Вы можете получить доступ ко всему с помощью объекта Customer с помощью

Hashmap<Customer, Order> map = new HashMap<Customer, Order>();
map.put(c, o);

Теперь, почему вы предпочитаете это?

Может быть, в вашем ресторане у вас есть несколько Клиентов, которых называют «Боб» в эту конкретную ночь, поэтому просто иметь HashMap имен уже недостаточно. Ваш класс Customer будет отражать различия между "Bob", но просто строка, представляющая каждого из них, не подойдет.

Имея HashMap of Customers, вы можете просто изменить алгоритм хеширования класса Customer, и все будет работать идеально (надеюсь). Если вы продолжили работу со строками, было бы нелегко вносить изменения и однозначно идентифицировать каждый экземпляр объекта

1 голос
/ 14 марта 2011

Как сказал Марк Эллиот, иногда существует естественный ключ, который не имеет естественной строковой формы. Почему бы не использовать его?

Строки достаточно хороши, когда у вас есть удобная форма String или она очевидна, например, когда вы имеете дело с объектами базы данных.

Однако производительность является еще одной причиной.

Конечно, если вы реализуете пользовательский ключ, вы должны АБСОЛЮТНО убедиться, что он неизменен. это не только предпочтение, как говорит trashgod. Кроме того, Comparable довольно не имеет значения.

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

1 голос
/ 14 марта 2011

Представьте себе случай, когда вы хотите создать карту, основанную на типе и имени пользователя.В этом случае вам лучше всего написать класс, состоящий из 2 полей (и переопределяющих hashCode и equals).Использование в этом случае одной строки и попытка каким-то образом объединить эти 2 фрагмента информации в одну строку будет очень неудобным и подверженным ошибкам.

0 голосов
/ 27 июля 2012

Преимущества:
1) неизменяемость строки => Thread Safe , нет проблем с параллелизмом
2) хеш-код строки кэшируется (ищитеприватный int хеш в JDK для класса String).Экономит много времени на обработку.
3) Пул строк для литералов (повторное использование строковых объектов) или внутренних строк, созданных с помощью оператора new для добавления их в пул
4) Безопасность, никто не может редактировать ключ
5) Равен и хэш-код реализован хорошо

Недостаток:
1) Пул строк представляет угрозу безопасности при открытии пароля в открытом видетекст для тех, кто имеет доступ к памяти Java-приложения.Основной дамп java-приложения, генерирующий дамп памяти в / tmp, может поставить пароли в реальную угрозу.
Решение : Для паролей используйте char [] . Вы можете стереть конвенции, установив его пустым.или любой другой символ, который снижает риск раскрытия пароля.

0 голосов
/ 14 марта 2011

Полагаю, вы могли бы сказать, что String "достаточно хорош", потому что вы можете превратить типичные типы ключей в String.Однако выполнение этого может быть дорогостоящим по сравнению со стоимостью использования типа реального ключа в качестве ключа хеш-таблицы.Рассмотрим, например, преобразование Integer (или int) в строку каждый раз, когда вы хотите использовать его в качестве ключа хеш-таблицы ...

Другой момент заключается в реализации hashCode и equals для типа ключа очень просто.Настолько легко, что IDE, такие как Eclipse, могут генерировать эти два метода для вас.

0 голосов
/ 14 марта 2011

Строки, вероятно, являются наиболее распространенным вариантом использования, но это действительно зависит от того, что вы хотите сохранить.Вы не хотели бы превращать Лонга в Строку только для того, чтобы ваш ключ был Строкой.Просто используйте тип в соответствии с вашими структурами данных.Для таких типов, как, например, Long, вам также не нужно реализовывать hashCode / equals.Если вы думаете о пользовательских классах, реализующих equals, и hashCode может быть хорошей идеей в любом случае.Реализация его с помощью, например, Apache Commons 'EqualBuilder также довольно проста.

...