У меня есть 2D-массив целых чисел. Я хочу, чтобы они были помещены в HashMap. Но я хочу получить доступ к элементам из HashMap на основе индекса массива. Что-то вроде:
Для A [2] [5], map.get(2,5)
который возвращает значение, связанное с этим ключом. Но как мне создать хэш-карту с парой ключей? Или, в общем, несколько ключей: Map<((key1, key2,..,keyN), Value)
таким образом, чтобы я мог получить доступ к элементу с помощью get (key1, key2, ... keyN).
РЕДАКТИРОВАТЬ: через 3 года после публикации вопроса я хочу добавить к нему немного больше
Я нашел другой способ для NxN matrix
.
Индексы массива i
и j
могут быть представлены как единый key
следующим образом:
int key = i * N + j;
//map.put(key, a[i][j]); // queue.add(key);
А индексы можно вернуть key
следующим образом:
int i = key / N;
int j = key % N;
Ответы:
Есть несколько вариантов:
2 измерения
Карта карт
Обертка ключевого объекта
Реализация
equals()
иhashCode()
здесь имеет решающее значение. Тогда вы просто используете:и:
Table
из ГуавыTable
использует карту карт внизу.Размеры N
Обратите внимание, что специальный
Key
класс - единственный подход, который масштабируется до n измерений. Вы также можете рассмотреть:но это ужасно с точки зрения производительности, а также читабельности и правильности (непростой способ установить размер списка).
Может быть, взгляните на Scala, где у вас есть кортежи и
case
классы (замена всегоKey
класса однострочным).источник
Map.Entry<K, V>
в качестве ключа?Map<Pair<Key1, Key2>, Value>
?hashCode()
это также может быть реализовано с помощью одной строки какObjects.hash(x,y)
Когда вы создаете свой собственный объект пары ключей, вы должны столкнуться с некоторыми проблемами.
Во-первых, вы должны знать о реализации
hashCode()
иequals()
. Вам нужно будет это сделать.Во-вторых, при внедрении
hashCode()
убедитесь, что вы понимаете, как это работает. Данный пример пользователяна самом деле одна из худших реализаций, которые вы можете сделать. Причина проста: у вас много одинаковых хешей! И
hashCode()
должен возвращать значения типа int, которые, как правило, бывают редкими, в лучшем случае уникальными. Используйте что-то вроде этого:Это быстро и возвращает уникальные хэши для ключей от -2 ^ 16 до 2 ^ 16-1 (от -65536 до 65535). Это подходит практически в любом случае. Очень редко вы выходите за эти границы.
В-третьих, при реализации
equals()
также знайте, для чего он используется, и знайте, как вы создаете свои ключи, поскольку они являются объектами. Часто вы делаете ненужные инструкции if, потому что у вас всегда будет один и тот же результат.Если вы создаете такие ключи:
map.put(new Key(x,y),V);
вы никогда не сравните ссылки на свои ключи. Потому что каждый раз, когда вы хотите получить доступ к карте, вы будете делать что-то вродеmap.get(new Key(x,y));
. Поэтому вамequals()
не нужно утверждение вродеif (this == obj)
. Этого никогда не будет .Вместо того , чтобы
if (getClass() != obj.getClass())
в вашемequals()
лучшем использованииif (!(obj instanceof this))
. Это будет справедливо даже для подклассов.Итак, единственное, что вам нужно сравнить, это на самом деле X и Y. Итак, лучшая
equals()
реализация в этом случае будет:Итак, в итоге ваш ключевой класс выглядит так:
Вы можете указать свои индексы измерения
X
иY
уровень публичного доступа, поскольку они являются окончательными и не содержат конфиденциальной информации. Я не уверен на 100%, правильно лиprivate
работает уровень доступа в любом случае при приведенииObject
к файлуKey
.Если вас интересует финал, я объявляю все окончательным, значение которого устанавливается при создании экземпляра и никогда не изменяется - и поэтому является константой объекта.
источник
У вас не может быть хэш-карты с несколькими ключами, но у вас может быть объект, который принимает несколько параметров в качестве ключа.
Создайте объект с именем Index, который принимает значения x и y.
Тогда
HashMap<Index, Value>
получите результат. :)источник
hashCode
иequals
.Реализовано в общих коллекциях MultiKeyMap
источник
Две возможности. Либо используйте комбинированный ключ:
Или карту карты:
источник
hashCode
иequals
методах.Используйте в
Pair
качестве ключей дляHashMap
. JDK не имеет пары, но вы можете использовать стороннюю библиотеку, такую как http://commons.apache.org/lang, или написать свой собственный тайпе пары.источник
Создайте класс значений, который будет представлять ваш составной ключ, например:
заботясь об отмене
equals()
иhashCode()
правильно. Если это кажется большой работой, вы можете рассмотреть несколько готовых универсальных контейнеров, например,Pair
предоставляемых Apache Commons среди других.Здесь также есть много похожих вопросов с другими идеями, такими как использование таблицы Guava , хотя позволяет ключам иметь разные типы, которые могут быть излишними (с точки зрения использования памяти и сложности) в вашем случае, поскольку я понимаю, что ваши ключи являются целыми числами.
источник
Если это два целых числа, вы можете попробовать быстрый и грязный трюк:
Map<String, ?>
использовать ключ asi+"#"+j
.Если ключ
i+"#"+j
такой же, какj+"#"+i
попробуйтеmin(i,j)+"#"+max(i,j)
.источник
String
с забавными последствиями.i#j = j#i
приi == j
таком использованииmin/max
трюка не пойдет.5#5
и5#5
поменять местами?5#3
иметь такой же хэш, как3#5
, тогда вы используете min / max для обеспечения соблюдения3#5
в этом порядке.Вы также можете использовать для этого реализацию таблицы гуавы .
Таблица представляет собой специальную карту, в которой два ключа могут быть указаны вместе, чтобы ссылаться на одно значение. Это похоже на создание карты карт.
источник
Вы можете создать свой ключевой объект примерно так:
public class MapKey {
}
Преимущество этого: он всегда будет следить за тем, чтобы вы также охватывали все сценарии Equals.
ПРИМЕЧАНИЕ . Ваши ключи key1 и key2 должны быть неизменными. Только тогда вы сможете построить стабильный ключевой Объект.
источник
мы можем создать класс для передачи более одного ключа или значения, и объект этого класса можно использовать в качестве параметра в карте.
источник
Вы можете скачать его по ссылке ниже: https://github.com/VVS279/DoubleKeyHashMap/blob/master/src/com/virtualMark/doubleKeyHashMap/DoubleKeyHashMap.java
https://github.com/VVS279/DoubleKeyHashMap
Вы можете использовать двойной ключ: значение hashmap,
источник