Если я прохожу те же клавишу несколько раз HashMap
«S put
методом, что происходит с первоначальным значением? А что если даже значение повторяется? Я не нашел никакой документации по этому вопросу.
Случай 1: перезаписанные значения для ключа
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));
Мы получаем surely not one
.
Случай 2: Дублирующее значение
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));
Мы получаем one
.
Но что происходит с другими ценностями? Я преподавал основы студенту, и меня спросили об этом. Это Map
как корзина, где указано последнее значение (но в памяти)?
Ответы:
По определению
put
команда заменяет предыдущее значение, связанное с данным ключом на карте (концептуально, как операция индексации массива для примитивных типов).Карта просто сбрасывает ссылку на значение. Если ничто иное не содержит ссылку на объект, этот объект становится пригодным для сборки мусора. Кроме того, Java возвращает любое предыдущее значение, связанное с данным ключом (или,
null
если его нет), так что вы можете определить, что там было, и при необходимости сохранить ссылку.Больше информации здесь: HashMap Doc
источник
Вы можете найти свой ответ в javadoc Map # put (K, V) (который на самом деле что-то возвращает):
Таким образом, если вы не присваиваете возвращаемое значение при вызове
mymap.put("1", "a string")
, оно просто перестает ссылаться и, следовательно, может быть использовано для сборки мусора.источник
null
) как описано чуть выше в Javadoc так, да, это то , что я имею в виду. Это действительно может быть неправильно истолковано?Предыдущее значение для ключа сбрасывается и заменяется новым.
Если вы хотите сохранить все значения, заданные ключом, вы можете рассмотреть возможность реализации чего-то вроде этого:
источник
это функция «ключ / значение», и вы не можете иметь дубликат ключа для нескольких значений, потому что, когда вы хотите получить фактическое значение, одно из значений которого принадлежит введенному ключу
в вашем примере, когда вы хотите получить значение «1», какое из них является Это ?!
это причина иметь уникальный ключ для каждого значения, но вы могли бы использовать трюк с помощью стандартной библиотеки Java:
и вы могли бы использовать это таким образом:
и результат отпечатков:
источник
Связывает указанное значение с указанным ключом в этой карте. Если карта ранее содержала сопоставление для ключа, старое значение заменяется.
источник
Он заменяет существующее значение на карте для соответствующего ключа. И если не существует ключа с таким именем, он создает ключ с указанным значением. например:
ВЫВОД Ключ = "1", значение = "два"
Итак, предыдущее значение перезаписывается.
источник
На ваш вопрос, была ли карта похожа на ведро: нет.
Это как список с
name=value
парами, тогда какname
как не обязательно быть строкой (хотя может).Чтобы получить элемент, вы передаете свой ключ в метод get (), который возвращает вам назначенный объект.
И хэш карта означает , что если вы пытаетесь восстановить свой объект , используя GET-метод, он не будет сравнивать реальный объект , который вы при условии, потому что нужно будет перебирать свой список и сравнить () ключ Вы предоставили текущий элемент.
Это было бы неэффективно. Вместо этого, независимо от того, из чего состоит ваш объект, он вычисляет так называемый хэш-код из обоих объектов и сравнивает их. Проще сравнить два
int
s вместо двух целых (возможно, очень сложных) объектов. Вы можете представить себе хеш-код в виде сводки, имеющей предопределенную длину (int), поэтому он не уникален и имеет коллизии. Правила для хэш-кода вы найдете в документации, на которую я вставил ссылку.Если вы хотите узнать больше об этом, вы можете взглянуть на статьи на javapractices.com и technofundo.com
С уважением
источник
Я всегда использовал:
если бы я хотел применить несколько вещей к одному идентифицирующему ключу.
Вы всегда можете сделать что-то подобное и создать себе лабиринт!
источник
Карты из JDK не предназначены для хранения данных под дублированными ключами.
В лучшем случае новое значение переопределит предыдущие.
Хуже сценарий является исключением (например, когда вы пытаетесь собрать его в виде потока):
Нет дубликатов:
Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))
Дублированный поток:
Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))
Для работы с дублированными ключами - используйте другой пакет, например: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html.
Существует много других реализаций, имеющих дело с дублированными ключами. Они необходимы для Интернета (например, дублированные ключи cookie, заголовки Http могут иметь те же поля, ...)
Удачи! :)
источник
Collectors.toMap()
имеет третий аргумент - функцию слияния. Если мы хотим просто переопределить последний дубликат элемента:Stream.of("one", "two", "one").collect(Collectors.toMap(x -> x, x -> x, (key1, key2) -> key2))
. ссылка"one", "not one", "surely not one"
не будет выдавать дубликатов ошибок ключа, потому что все строки разные.Кстати, если вы хотите некоторую семантику, например, поставить, если этот ключ не существует. Вы можете использовать
concurrentHashMap
сputIfAbsent()
функцией. Проверь это:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K,%20V)
concurrentHashMap
Потокобезопасен с высокой производительностью, поскольку использует механизм « чередования блокировок » для повышения пропускной способности.источник
Да, это означает, что все 1 ключи со значением перезаписываются последним добавленным значением, и здесь вы добавляете «наверняка не один», поэтому он будет отображать только «наверняка не один».
Даже если вы пытаетесь отобразить с циклом, он также будет отображать только один ключ и значение, которые имеют тот же ключ.
источник
Означает, что хеш-карта не допускает дублирования, если вы правильно переопределили методы equals и hashCode ().
HashSet также использует HashMap для внутреннего использования, см. Исходный документ
источник