Если у меня есть значение "foo"
и HashMap<String> ftw
для которого ftw.containsValue("foo")
возвращается true
, как я могу получить соответствующий ключ? Должен ли я пройти через хэш-карту? Каков наилучший способ сделать это?
452
public static final String TIME = "time";
иproperties.put(TIME, PbActivityJpa_.time);
Ответы:
Если вы решите использовать библиотеку Commons Collections вместо стандартного API Java Collections, вы сможете легко добиться этого.
Интерфейс BidiMap в библиотеке коллекций представляет собой двунаправленную карту, позволяющую сопоставить ключ со значением (например, карты нормалей), а также сопоставить значение ключу, что позволяет выполнять поиск в обоих направлениях. Получение ключа для значения поддерживается методом getKey () .
Однако есть предостережение: двунаправленные карты не могут иметь несколько значений, сопоставленных с ключами, и, следовательно, если в вашем наборе данных нет сопоставлений 1: 1 между ключами и значениями, вы не можете использовать бидимапы.
Обновить
Если вы хотите использовать API коллекций Java, вам необходимо обеспечить соотношение 1: 1 между ключами и значениями во время вставки значения в карту. Это легче сказать, чем сделать.
Как только вы сможете убедиться в этом, используйте метод entrySet () для получения набора записей (отображений) на карте. Как только вы получили набор, тип которого Map.Entry , выполните итерацию записей, сравнив сохраненное значение с ожидаемым, и получите соответствующий ключ .
Обновление № 2
Поддержку двунаправленных карт с обобщениями можно найти в Google Guava и переработанных библиотеках Commons-Collections (последняя не является проектом Apache). Спасибо Esko за указание на отсутствующую общую поддержку в коллекциях Apache Commons. Использование коллекций с обобщениями делает более понятным код.
источник
Если структура данных имеет много-однозначное соответствие между ключами и значениями следует перебирать не записи и выбрать все подходящие ключи:
В случае отношения « один к одному» вы можете вернуть первый соответствующий ключ:
В Java 8:
Кроме того, для пользователей Guava, BiMap может быть полезным. Например:
источник
o(1)
. Если вы перебираете значения, это снижает производительность. Если вы хотитеbetter performance
иone-one
имеете отношения, вы можете использоватьanother map
гдеvalue is a key
.filter(entry -> entry.getValue().equals(value))
на, так как не было сделано никаких заявлений о способностях. Далее можно заменить на.filter(entry ->
Objects.equals
(entry.getValue(), value))
null
.map(entry -> entry.getKey())
.map(Map.Entry::getKey)
Некоторая дополнительная информация ... Может быть полезно для вас
Приведенный выше метод может быть не очень хорошим, если ваш hashmap действительно большой. Если ваша хэш-карта содержит уникальный ключ для сопоставления уникального значения, вы можете сохранить еще одну хэш-карту, которая содержит отображение из значения в ключ.
То есть вы должны поддерживать два хеш-карты
В этом случае вы можете использовать второй hashmap для получения ключа.
источник
Я думаю, что ваш выбор
entrySet()
и, чтобы найти ключи, которые соответствуют значению. Это самый медленный метод, поскольку он требует итерации всей коллекции, в то время как два других метода этого не требуют.источник
Вы можете вставить ключ, пару значений и ее инверсию в структуру карты
Использование map.get ("theValue") вернет "theKey".
Это быстрый и грязный способ создания постоянных карт, который будет работать только для нескольких избранных наборов данных:
источник
Украсьте карту своей собственной реализацией
источник
Здесь нет однозначного ответа, потому что несколько ключей могут отображаться на одно и то же значение. Если вы применяете уникальность в своем собственном коде, лучшее решение - создать класс, который использует два Hashmaps для отслеживания отображений в обоих направлениях.
источник
Чтобы найти все ключи, которые соответствуют этому значению, выполните итерацию по всем парам в hashmap, используя
map.entrySet()
.источник
Используя Java 8:
источник
value=="foo"
так не пойдет.equals
следует использовать для сравнения строк.value
не был интернирован.Если вы строите карту в своем собственном коде, попробуйте соединить ключ и значение на карте:
Затем, когда у вас есть значение, у вас также есть ключ.
источник
Я думаю, что это лучшее решение, оригинальный адрес: Java2s
Простое использование: если вы поместили все данные в hasMap и у вас есть item = "Automobile", значит, вы ищете его ключ в hashMap. это хорошее решение.
источник
Боюсь, вам просто придется повторить свою карту. Самое короткое, что я мог придумать:
источник
источник
Похоже, лучший способ для вас - перебирать записи, используя,
map.entrySet()
так как,map.containsValue()
вероятно, делает это в любом случае.источник
Для API таргетинга разработки Android <19 Виталий Федоренко решение «один к одному» не работает, потому что
Objects.equals
не реализовано. Вот простая альтернатива:источник
Вы можете использовать ниже:
источник
Да, вам нужно пройтись по хэш-карте, если вы не реализуете что-то вроде того, что предлагают эти различные ответы. Вместо того, чтобы возиться с entrySet, я просто получил бы keySet (), перебрал бы этот набор и сохранил (первый) ключ, который возвращает вам ваше подходящее значение. Если вам нужны все ключи, которые соответствуют этому значению, очевидно, вы должны сделать все это.
Как предполагает Джонас, это может уже быть тем, что делает метод containsValue, так что вы можете просто пропустить этот тест все вместе и просто выполнять итерацию каждый раз (или, возможно, компилятор уже устранит избыточность, кто знает).
Кроме того, относительно других ответов, если ваша обратная карта выглядит так
вы можете иметь дело с неуникальными сопоставлениями ключ-значение, если вам нужна эта возможность (распутывая их в стороне). Это включило бы отлично в любое из решений, которые люди предлагают здесь, используя две карты.
источник
Вы можете получить ключ, используя значения, используя следующий код:
источник
источник
String
как ключ и значение. Когда я звоню,map.add("1", "2"); map.add("1","3");
я могу позвонитьmap.getKey("2");
и получить"1"
, хотя"1"
это ключ для"3"
.getValue("1")
вернется3
.В java8
источник
источник
источник
источник
источник
Используйте тонкую обертку: HMap
источник
Мои 2 цента. Вы можете получить ключи в массиве, а затем перебрать массив. Это повлияет на производительность этого блока кода, если карта довольно большая, когда вы сначала получаете ключи в массиве, которые могут занимать некоторое время, а затем цикл. В противном случае для небольших карт все должно быть в порядке.
источник
Я думаю, что keySet () может быть хорошо для нахождения ключей, соответствующих значению, и имеет лучший стиль кодирования, чем entrySet () .
Пример:
Предположим, у вас есть карта HashMap , ArrayList res , значение, в котором вы хотите найти все сопоставления ключей , а затем сохранить ключи в res .
Вы можете написать код ниже:
вместо того, чтобы использовать entrySet () ниже:
Надеюсь, поможет :)
источник
map.get(key) == value
не очень хорошая идея при проверке равенства объектов, так как вы сравниваете ссылки. Объект равенства всегда должен использовать их.equals()
Хотя это не дает прямого ответа на вопрос, оно связано.
Таким образом, вам не нужно продолжать создавать / повторять. Просто создайте обратную карту один раз и получите то, что вам нужно.
источник
Важно отметить, что после этого вопроса Apache Collections поддерживает общие двунаправленные карты . Таким образом, некоторые из наиболее популярных ответов больше не являются точными в этом вопросе.
Для Serialized BidiMap, который также поддерживает повторяющиеся значения (сценарий 1-ко-многим), также рассмотрите MapDB.org .
источник
Если вы хотите получить ключ по значению, лучше всего использовать двунаправленную карту (двунаправленные карты), вы можете получить ключ по значению за O (1) раз.
Но недостатком этого является то, что вы можете использовать только уникальный набор ключей и набор значений.
В Java есть структура данных, которая называется Table , которая представляет собой не что иное, как карту
Таблица <A, B, C> == карта <A, карта <B, C>>
Здесь вы можете получить
map<B,C>
, запросивT.row(a);
, и вы также можете получитьmap<A,C>
, запросивT.column(b);
В вашем особом случае вставьте C как некоторую константу.
Итак, это как <a1, b1, 1> <a2, b2, 1>, ...
Так что, если вы найдете через T.row (a1) ---> возвращает карту -> получить набор ключей, эта возвращенная карта.
Если вам нужно найти значение ключа, T.column (b2) -> возвращает карту -> получить набор ключей возвращенной карты.
Преимущества перед предыдущим случаем:
источник