HashMap.containsValue — в чем смысл?

У меня есть HashMap, и мне нужно получить элемент по его целочисленному значению. Я заметил, что есть функция containsValue(), но, похоже, мне все равно придется перебирать карту, чтобы найти правильный индекс.

Мой вопрос; зачем использовать containsValue(), если мне нужно пройти его потом?

Кроме того, я полностью упускаю суть? ;-)


person Frederik    schedule 29.03.2010    source источник


Ответы (7)


Карта сопоставляет ключ со значением. Если у вас есть значение, и вы знаете, что карта содержит это значение, зачем вам еще нужен ключ?

С другой стороны, если вам действительно нужен ключ или у вас есть только свойство значения, вы можете повторить entrySet(), проверить значение и вернуть ключ, если он найден:

for (Map.Entry<Index,Value> entry : map.entrySet()) {
  if (entry.getValue().getXy().equals(xy)) {
    return entry.getKey();
  }
}
person Arne Burmeister    schedule 29.03.2010

Карта — это ключ к ценностному хранилищу. Сказать, что значение содержится, дается только как указание. Я думаю, что для получения биективной ссылки, позволяющей извлекать ключ из значения, вам придется полагаться на такие вещи, как BiMap из коллекций google

person Riduidel    schedule 29.03.2010

Вам не обязательно проходить его потом. containsValue() полезен в ситуациях, когда вам не нужно точно знать, где находится ваше значение, а скорее, когда вам нужно только знать, есть ли оно уже на карте. В ситуациях, когда вам нужно точно знать, где на карте находится значение, не беспокойтесь об использовании containsValue() — перейдите прямо к итератору и найдите его.

person Jim Kiley    schedule 29.03.2010

HashMap (или карта вообще) использует пары ключ/значение. Когда вы добавляете что-то на карту, вы должны указать ключ, и именно этот ключ используется позже при извлечении значения. На основе реализации HashMap при наличии ключа извлечение значения выполняется за время O(1).

containsValue — полезный метод для проверки того, что HashMap содержит искомое значение, но я действительно не понимаю, почему вы используете его для получения искомого значения??

Правильный способ использования карты будет выглядеть примерно так:

HashMap<Integer, Object> myMap = new HashMap<Integer, Object>();
myMap.put(1, object1);
myMap.put(2, object2);
myMap.put(3, object3);

Теперь вы можете получить свои объекты, выполнив:

Object myObject = myMap.get(1);

Если вы сделали:

моя карта.containsValue (1);

это вернет false, поскольку 1 является ключом, а не значением. Вы можете сделать:

myMap.containsKey(1);

если вы просто хотите знать, существует ли он, но нет проблем с вызовом:

Object myObject = myMap.get(99);

он просто вернул бы ноль, если бы не было ключа, 99.

Итак, суть в том, что вы правы, нет смысла использовать containsValue, когда вы пытаетесь получить значение. Используйте get или containsKey, если вы хотите сначала проверить существование.

person DaveJohnston    schedule 29.03.2010

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

person sanjuro    schedule 29.03.2010
comment
containsValue() будет проходить по HashMap: docjar.com/ html/api/java/util/HashMap.java.html#631 Если он хочет знать, находится ли значение в карте, эта информация должна храниться в отдельном наборе. - person Christoffer Hammarström; 29.03.2010
comment
да, я знаю, но его вопрос был в том, зачем использовать containsValue(), если мне нужно пройти его потом? поэтому я перевел это на то, почему containsValue хорош, если ему нужно будет пройти хэш-карту впоследствии (во второй раз). - person sanjuro; 29.03.2010

Позвольте мне переформулировать этот вопрос для Фредерика:

Хорошо, containsValue(), сравнивает ли он внутренне (его входной параметр) с каждым «значением» в хэш-карте? Или он каким-то образом использует хэш-код (или другую технику) для генерации результата? В первом случае мы могли бы просто использовать итератор для обхода и сопоставления существования нашего значения со всеми «значениями» хэш-карты. Значимость вопроса в производительности, или скорости!

person Vivek Vardhan    schedule 21.09.2016
comment
Я не понимаю, насколько полезно переформулировать вопрос в этом случае. - person andrel; 21.09.2016
comment
предыдущие ответы вырваны из контекста. - person Vivek Vardhan; 22.09.2016

Я думаю, что Map.containsValue — это ошибка в дизайне интерфейса карты.

Очень редко встречаются реализации Map, которые обеспечивают более быструю, чем линейная, реализацию containsValue. Например, карта может внутренне представлять каждое отдельное значение как небольшое целое число, а затем использовать битовые шаблоны для представления наборов значений. Такая карта могла бы определить за постоянное время, что она никогда раньше не видела данное значение (хотя для возврата утвердительного результата все еще может потребоваться линейное время).

Однако операция, которая иногда требует линейного времени, а иногда требует постоянного времени, не является полезной основой для универсального алгоритма. Вы не можете заменить LinkedList на ArrayList и ожидать, что все будет работать хорошо, даже если они оба поддерживают произвольный доступ в своем API. Клиент, которому требуется константное значение containsValue, должен поддерживать отдельный набор значений HashSet, чтобы гарантировать хорошую производительность. Клиенты, довольные производительностью за линейное время, могут просто написать цикл самостоятельно.

Даже если сопровождающие интерфейса Map также сожалеют о добавлении containsValue, они, конечно же, не могут удалить его сейчас.

person Alan A Donovan    schedule 29.06.2019