Почему в интерфейсе карты есть метод «удалить (ключ, значение)»?

Я только что узнал, что Map предоставляет метод для «[удаления] записи для указанного ключа, только если она в настоящее время сопоставлена ​​с указанным значением.». Он определяется как:

default boolean remove(Object key, Object value)

Я не могу придумать причин для включения этого метода в интерфейс своих собственных карт. Мне интересно, а зачем кому-то это делать? Может ли кто-нибудь привести пример алгоритма, незаменимого по умолчанию remove(key) (без параметра «значение»)?

Вам не нужно включать его, поскольку он поставляется с реализацией по умолчанию.

Henry 25.12.2020 12:02

Не включайте в свой интерфейс ничего, что вам не нужно или вы не знаете, нужно ли оно вам.

Joakim Danielson 25.12.2020 12:07

@ Генри, я никогда не упоминал о расширении Java Map. Я говорил о разработке собственных пользовательских карт, возможно, вообще вне Java.

Captain Trojan 25.12.2020 12:15

@JoakimDanielson Вот почему я разместил вопрос, чтобы найти возможные варианты использования этой конкретной части интерфейса. Разве ты не понял этого?

Captain Trojan 25.12.2020 12:16

«Мне любопытно, зачем кому-то это делать? Бесплатная репутация для любого, кто придумает самый минимальный пример». map.remove(k, v);. Я хочу сделать это, потому что это удовлетворяет моим требованиям.

Andy Turner 25.12.2020 12:22

Хороший вопрос @AndyTurner, я переопределю задачу.

Captain Trojan 25.12.2020 12:23

Я не думаю, что вопрос так уж плох. Понятия не имею, почему так много минусов.

Beko 25.12.2020 12:40

При этом я имею в виду, что это просто removeValue. Точно так же, как remove(key) удаляет ключ, если он присутствует, этот удаляет значение определенного ключа, если он присутствует. Я не могу придумать какой-либо сценарий из головы, хотя. Но если это кому-то когда-нибудь понадобится, я думаю, оно там.

Beko 25.12.2020 12:47

Но это моя точка зрения, не реализуйте ее, если не видите в ней необходимости. По крайней мере, если вы создаете интерфейс для собственного использования.

Joakim Danielson 25.12.2020 12:52

@Beko Приятно иметь хотя бы одного человека, который понимает, очень ценю :) По делу: remove(value) в чем-то есть смысл, например, если процедура генерации ключей внезапно изменится, и вы не сможете найти соответствующий key для ваш value больше. Но remove(key, value)? Нужно иметь всю информацию: и key, и value, честно говоря, для меня это не имеет смысла. «Но если кому-то это когда-нибудь понадобится, я думаю, оно там». - да, это почти мое нынешнее состояние. Что неоптимально.

Captain Trojan 25.12.2020 13:17

Проблема с вашим вопросом также заключается в том, что если кто-то придумал пример использования, действительность этого варианта использования будет зависеть от того, какие другие методы у вас есть в интерфейсе или что можно сделать, например, с потоком. Таким образом, в этом случае лучшим вопросом может быть «Как удалить (ключ, значение) вписаться в остальную часть моего интерфейса?».

Joakim Danielson 25.12.2020 13:37

@JoakimDanielson Честно говоря, какая разница, вижу я что-то или чего-то не вижу. Я здесь, чтобы учиться, а не показывать.

Captain Trojan 25.12.2020 13:37

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

Joakim Danielson 25.12.2020 13:40

@JoakimDanielson Если кто-то придумал пример использования, действительность этого варианта использования может быть защищена этим человеком, как бы он ни говорил, даже с использованием других частей интерфейса или потоков или чего-то еще, на самом деле. Насколько я могу судить, я не налагал никаких ограничений на то, что должна содержать защита аргумента использования.

Captain Trojan 25.12.2020 13:40

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

Joakim Danielson 25.12.2020 13:44

@JoakimDanielson После этого комментария я надеюсь, что смысл этого вопроса, то есть выяснить, существуют ли мыслимые нетривиальные приложения remove(key, value) в АТД карты с деталями реализации, определенными в Java, вам ясен. Я знаю как факт, что я регулярно не могу правильно объяснить проблемы, поэтому не стесняйтесь предлагать изменения вопросов, которые соответствуют этому конкретному моему вопросу, кроме, конечно, попытки ответить на вопрос самостоятельно.

Captain Trojan 25.12.2020 13:44

@JoakimDanielson Я ценю тот факт, что вы первый, кто предложил реальный пример, но, пожалуйста, опубликуйте ответ вместо комментария, чтобы мы могли обсудить этот ответ в отдельном месте.

Captain Trojan 25.12.2020 13:46

Нвм мои комментарии. Я думал, что он удаляет значения, но, прочитав обновление @Dorian и перепроверив документы, я увидел, что он фактически удаляет ключ. Сорри за путаницу.

Beko 25.12.2020 14:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
18
455
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Javadoc этого метода объясняет это:

Реализация по умолчанию эквивалентна для этой карты:

 if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
     map.remove(key);
     return true;
 } else
     return false;
 

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

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

Это полезно при параллельном программировании, когда несколько потоков обращаются к одной и той же карте. Вам понадобится ConcurrentHashMap, который обеспечивает гарантии атомарности для remove(Object, Object).

Например, что-то вроде этого (представьте, что ConcurrentHashMap<String, String> cache делится между потоками):

String key = ...;
String value = cache.get(key);
//long lasting operation
cache.remove(key, value);

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

Ну, во-первых, Javadoc абсолютно ничего не объясняет о потенциальном использовании, которое является всей и единственной темой этого вопроса, а во-вторых, я никогда не упоминал о расширении Java Map, а скорее о разработке собственных пользовательских карт, которые могут существенно отличаться от Java Map или быть разработанным на другом языке. Этот вопрос касается абстрактного дизайна и интерфейса АТД, Карты и того, зачем вам когда-либо remove за key, только если есть ожидаемый value в map.get(key).

Captain Trojan 25.12.2020 12:20

@CaptainTrojan Я добавил набросок примера. Надеюсь, это поможет, не могу придумать ничего более конкретного, чем это.

Dorian Gray 25.12.2020 14:23

Отлично, не подумал об этом. Хороший вопрос, спасибо за объяснение.

Captain Trojan 26.12.2020 02:37

Другие вопросы по теме