Java - Почему Map.put () перезаписывает, а Set.add () нет? - PullRequest
20 голосов
/ 05 июня 2010

Мне интересно, в чем причина того, что Java Map.put(key, value) перезаписывает эквивалентно ключевые значения, которые уже находятся в коллекции, в то время как Set.add(value) не перезаписывает ранее существующее эквивалентное значение, которое уже находится в коллекции?

Редактировать:

Похоже, что точка зрения большинства состоит в том, что объекты в наборе, которые оценивают равенство, должны быть равны во всех отношениях, поэтому не должно иметь значения, переписывает ли Set.add (Object)равноценные объекты или нет.Если два объекта оцениваются на равенство, но на самом деле содержат разные данные, тогда коллекция типа Map является более подходящим контейнером.

Я несколько не согласен с этой точкой зрения.
Пример: набор, содержащий группу объектов "Персона".Чтобы обновить некоторую информацию об этом человеке, вы можете передать в набор новый обновленный объект персоны, чтобы перезаписать старый, устаревший объект персоны.В этом случае Person будет иметь первичный ключ, который идентифицирует этого человека, и набор будет идентифицировать и сравнивать людей только на основе их первичных ключей.Этот первичный ключ является частью личности человека, в отличие от внешней ссылки, такой как карта.

Ответы [ 4 ]

9 голосов
/ 05 июня 2010

Поведение Map позволяет изменять значения, связанные с эквивалентными ключами. Это довольно распространенный вариант использования: a : b становится a : c.

Да, перезапись Set содержимого с помощью add может что-то изменить (справочное значение) - но это выглядит как довольно узкий вариант использования (который может быть выполнен в любом случае - всегда пытайтесь удалить перед добавлением: s.remove(o); s.add(o); ) относительно того, что можно было бы получить в большинстве случаев - ничего для циклов.

редактирование:

единственное потенциальное использование, которое я мог видеть для такого поведения, - это ограниченный бюджет памяти, создание множества тяжелых, но эквивалентных объектов и ссылки на разные равные версии в разных местах, предотвращая сборку мусора дублирующихся , Однако, столкнувшись с этой проблемой раньше, я не думаю, что такое поведение - даже лучший способ ее решить.

5 голосов
/ 05 июня 2010

На мой взгляд, нет смысла что-то перезаписывать в Set, так как ничего не изменится.

Однако при обновлении карты ключ может быть тем же, но значение может быть другим.

1 голос
/ 22 марта 2012

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

0 голосов
/ 05 июня 2010

Я не согласен с предпосылкой вашего вопроса. И Map, и Set являются абстрактными интерфейсами. Независимо от того, перезаписаны они или нет, это деталь реализации.

  1. реализация Map, которая не перезаписывает .
  2. Вы можете создать изменяемый одноэлементный набор - добавление материала в набор заменяет существующее одноэлементное значение.
...