Добавляет ли дублирующее значение в HashSet/HashMap прежнее значение

Пожалуйста, рассмотрите приведенный ниже код:

HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)

hs.size() даст 1, поскольку HashSet не позволяет дублировать, так что будет сохранен только один элемент.

Я хочу знать, добавим ли мы повторяющийся элемент, заменим ли он предыдущий элемент или просто не добавим его?

Кроме того, что произойдет с помощью HashMap для одного и того же случая?

Ответ 1

В случае HashMap он заменяет старое значение новым.

В случае HashSet элемент не вставлен.

Ответ 2

Первое, что вам нужно знать, это то, что HashSet действует как Set, что означает, что вы добавляете свой объект непосредственно в HashSet и не можете содержать дубликаты. Вы просто добавляете свое значение непосредственно в HashSet.

Однако HashMap - это тип Map. Это означает, что каждый раз, когда вы добавляете запись, вы добавляете пару ключ-значение.

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

Понимание связи между HashMap и HashSet:

Помните, что HashMap не может иметь дубликаты ключей. За сценой HashSet используется HashMap.

Когда вы пытаетесь добавить какой-либо объект в HashSet, эта запись фактически сохраняется как ключ в HashMap - тот же HashMap, который используется за сценой HashSet. Поскольку для этого базового HashMap требуется пара ключ-значение, для нас создается фиктивное значение.

Теперь, когда вы пытаетесь вставить другой дублирующий объект в тот же HashSet, он снова попытается вставить его в качестве ключа в HashMap, лежащего под ним. Однако HashMap не поддерживает дубликаты. Следовательно, HashSet по-прежнему будет иметь только одно значение этого типа. В качестве побочного примечания для каждого повторяющегося ключа, поскольку значение, сгенерированное для нашей записи в HashSet, представляет собой случайное/фиктивное значение, ключ вообще не заменяется. он будет проигнорирован как удаление ключа и добавление обратно одного и того же ключа (значение фиктивного значения одинаково) не будет иметь никакого смысла.

Резюме:

HashMap позволяет дублировать values, но не keys. HashSet не может содержать дубликатов.

Чтобы воспроизвести, успешно ли завершено добавление объекта, вы можете проверить значение boolean, возвращаемое при вызове .add(), и посмотреть, возвращает ли он true или false. Если он вернул true, он был вставлен.

Ответ 3

docs довольно понятны: HashSet.add не заменяет:

Добавляет указанный элемент к этому набору, если он еще не присутствует. Более формально добавляет указанный элемент e к этому набору, если этот набор не содержит элемента e2, такого, что (e == null? E2 == null: e.equals(e2)). Если этот набор уже содержит элемент, вызов оставляет его неизменным и возвращает false.

Но HashMap.put заменит:

Если в карте ранее содержалось отображение для ключа, старое значение заменяется.

Ответ 4

Это случай HashSet, он НЕ заменяет его.

Из документов:

http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E)

"Добавляет указанный элемент к этому набору, если он еще не присутствует. Более формально добавляет указанный элемент e к этому набору, если этот набор не содержит элемента e2, такого, что (e == null? e2 == null: e.equals(e2)). Если это множество уже содержит элемент, вызов оставляет неизменным и возвращает false."

Ответ 5

Исправьте меня, если я ошибаюсь, но то, что вы получаете, это то, что со строками "Привет" == "Привет" не всегда получается правдой (потому что они не обязательно являются одним и тем же объектом).

Причина, по которой вы получаете ответ от 1, объясняется тем, что JVM будет, если это возможно, повторно использовать объекты строк. В этом случае JVM повторно использует строковый объект и, таким образом, перезаписывает элемент в Hashmap/Hashset.

Но вам не гарантировано такое поведение (потому что это может быть другой строковый объект с таким же значением "Привет" ). Поведение, которое вы видите, связано только с оптимизацией JVM.

Ответ 6

Сначала вам нужно проверить метод put на карте Hash, поскольку HashSet резервную копию HashMap

  • Когда вы добавляете дублирующее значение, скажите строку "Один" в HashSet,
  • Запись ( "one", PRESENT) будет вставлена ​​в Hashmap (для всех значения добавлены в набор, значение будет "НАСТОЯЩЕЕ", которое, если тип объекта)
  • Hashmap добавляет запись в Map и возвращает значение, которое в этом случае "PRESENT" или null, если запись отсутствует.
  • Метод добавления Hashset затем возвращает значение true, если возвращаемое значение из Hashmap равно null иначе false, что означает, что запись уже существует...

Ответ 7

Говорить по-другому: когда вы вставляете пару ключ-значение в HashMap, где ключ уже существует (в смысле hashvalue() дает одно и то же значение und equal(), это правда, но оба объекта все равно могут отличаться несколькими способами), ключ не заменяется, но значение перезаписывается. Ключ используется только для получения значения hashvalue() и нахождения значения в таблице с ним. Так как HashSet использует ключи HashMap и устанавливает произвольные значения, которые на самом деле не имеют значения (для пользователя), в результате элементы Elements of Set также не заменяются.

Ответ 8

В HashMap в основном содержится запись, в которой впоследствии содержатся ключи (Object) и Value (Object).Internally HashSet - это HashMap, а HashMap заменяет значения, поскольку некоторые из вас уже указывали... но действительно ли это заменяет ключи? Нет. и это трюк здесь. HashMap сохраняет свое значение как ключ в базовом HashMap, а значение - просто фиктивный объект. Поэтому, если вы пытаетесь повторно установить такое же значение в HashMap (ключ в базовой карте). Он просто заменяет фиктивное значение, а не ключ (значение для HashSet).

Посмотрите приведенный ниже код для класса HashSet:

public boolean [Подробнее...] добавить (E e) {

   return map.put(e, PRESENT)==null;
}

Здесь e - значение для HashSet, но ключ для базовой карты. и ключ никогда не заменяется. Надеюсь, что смогу устранить путаницу.