2012-03-19 1 views
5

Редактировать: теперь проблема правильная.Могу ли я иметь HashSets в качестве ключей в HashMap? Предложите альтернативу, если нет

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

HashMap<HashSet<String>, HashSet<Integer>> hm= ... 

для входов:

  1. манго, банан, яблоко

  2. яблоко, банан

  3. персик, морж

  4. морж, персик

Поскольку я читаю это, строчно, я создаю новые временные ключи (хешеты, которые еще не вставлены в hashmap) из сочетания слов в строке. Каждый временный ключ является хеш-множеством подмножества слов в строке. Если временный ключ уже существует в моем HashMap, которые я проверить,

if(hashmap.containsKey(hashset)) 

я просто добавить новую строку в соответствующее значение этого ключа, если нет, то я делаю новую запись в HashMap и заботиться о нем.

Ни в коем случае не могу изменить существующий ключ. Я только обновляю их соответствующие значения в hasmmap.

мой HashMap, в конце чтения файла, должен выглядеть примерно так

[яблоко, банан] = [1,2]

[персик, морж] = [3,4]

...

проблема заключается в том, что

if(hashmap.containsKey(hashset)) 

кусок кода не ALW ays обнаруживают существующие ключи. Почему это? Не разрешена ли эта структура?

Спасибо

+1

вы пробовали это? – pcalcao

+0

Не будет ли отображаться строка 5 на «персик, морж»? А как насчет «манго»? – Thomas

+0

@pcalcao да. он ведет себя странно. иногда он обнаруживает, что набор существует, иногда нет. Я просто хочу, чтобы проверка того, может ли HashMap обрабатывать hashset, имеет ключ. – student101

ответ

3

Вы можете, но как только вы добавили HashSet как ключ к HashMap вы не должны изменять его снова, как HashSet.hashCode() может измениться, и вы никогда не найдете HashSet снова. Другими словами, если вы делаете что-то вроде этого, убедитесь, что ваши ключи неизменны HashSets (смотри также Matt's answer here)

Альтернативой является использование MultiKeyMap вместе с MultiKey от commons collections

+0

+1, но почему он должен использовать альтернативу? Он мог бы просто переопределить 'equals' и' hashcode' в 'hashset' – Cratylus

+0

@ user384706: OP запросил возможную альтернативу –

+0

Хорошо, но он мог просто расширить' hashset' . Я не могу придумать, почему этого не достаточно – Cratylus

8

Это должно работать , но вам нужно следить за изменчивостью ключей. Если вы когда-либо измените содержимое одного из ключей, его хэш-код изменится, и ваша карта начнет делать странные вещи.Из Javadoc для Map:

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

Чтобы избежать этого, оберните ключи с Collections.unmodifiableSet() сразу после создания, или просто использовать ImmutableSet из гуавы.

+0

+1 Для упоминания карты Javadoc –

+0

@matt привет, я перефразировал вопрос сейчас. Это было не очень ясно объяснено. Ни в коем случае не меняю ключи, я только обновляю значения, на которые указывает точка в хэш-карте. – student101

1

Проблема, которая у вас есть, хорошо объясняется @Lukas ans @Matt.
Я думаю, вы могли бы уйти, используя расширение или использование рисунка декоратора, чтобы создать Hashset, который переоценивает equals и hashCode таким образом, который не зависит от содержимого.

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

+0

Это интересный вариант! Трудно сказать из текста OP, будет ли он выдавать желаемые результаты, хотя ... –

+0

Мне просто интересно, есть ли какая-то ошибка, которую я не вижу.ИМХО полезно избегать введения дополнительных библиотек, если вы их действительно не используете – Cratylus

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