Подтвердить что ты не робот

Java. Почему Map.put() перезаписывается, когда Set.add() не работает?

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

Изменить:

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

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

4b9b3361

Ответ 1

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

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

изменить:

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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