Я только что узнал, что Map
предоставляет метод для «[удаления] записи для указанного ключа, только если она в настоящее время сопоставлена с указанным значением.». Он определяется как:
default boolean remove(Object key, Object value)
Я не могу придумать причин для включения этого метода в интерфейс своих собственных карт. Мне интересно, а зачем кому-то это делать? Может ли кто-нибудь привести пример алгоритма, незаменимого по умолчанию remove(key)
(без параметра «значение»)?
Не включайте в свой интерфейс ничего, что вам не нужно или вы не знаете, нужно ли оно вам.
@ Генри, я никогда не упоминал о расширении Java Map
. Я говорил о разработке собственных пользовательских карт, возможно, вообще вне Java.
@JoakimDanielson Вот почему я разместил вопрос, чтобы найти возможные варианты использования этой конкретной части интерфейса. Разве ты не понял этого?
«Мне любопытно, зачем кому-то это делать? Бесплатная репутация для любого, кто придумает самый минимальный пример». map.remove(k, v);
. Я хочу сделать это, потому что это удовлетворяет моим требованиям.
Хороший вопрос @AndyTurner, я переопределю задачу.
Я не думаю, что вопрос так уж плох. Понятия не имею, почему так много минусов.
При этом я имею в виду, что это просто removeValue
. Точно так же, как remove(key)
удаляет ключ, если он присутствует, этот удаляет значение определенного ключа, если он присутствует. Я не могу придумать какой-либо сценарий из головы, хотя. Но если это кому-то когда-нибудь понадобится, я думаю, оно там.
Но это моя точка зрения, не реализуйте ее, если не видите в ней необходимости. По крайней мере, если вы создаете интерфейс для собственного использования.
@Beko Приятно иметь хотя бы одного человека, который понимает, очень ценю :) По делу: remove(value)
в чем-то есть смысл, например, если процедура генерации ключей внезапно изменится, и вы не сможете найти соответствующий key
для ваш value
больше. Но remove(key, value)
? Нужно иметь всю информацию: и key
, и value
, честно говоря, для меня это не имеет смысла. «Но если кому-то это когда-нибудь понадобится, я думаю, оно там». - да, это почти мое нынешнее состояние. Что неоптимально.
Проблема с вашим вопросом также заключается в том, что если кто-то придумал пример использования, действительность этого варианта использования будет зависеть от того, какие другие методы у вас есть в интерфейсе или что можно сделать, например, с потоком. Таким образом, в этом случае лучшим вопросом может быть «Как удалить (ключ, значение) вписаться в остальную часть моего интерфейса?».
@JoakimDanielson Честно говоря, какая разница, вижу я что-то или чего-то не вижу. Я здесь, чтобы учиться, а не показывать.
Я просто думаю, что реализация чего-то, в чем вы не видите необходимости, — это своего рода чрезмерная инженерия, и что лучше сосредоточиться на вещах, которые имеют значение, и сделать их как можно лучше. Но, конечно, если это только академический вопрос, и вы делаете это для развлечения, тогда вы можете пойти дальше и реализовать что-либо только в зависимости от того, считаете ли вы это интересным или нет.
@JoakimDanielson Если кто-то придумал пример использования, действительность этого варианта использования может быть защищена этим человеком, как бы он ни говорил, даже с использованием других частей интерфейса или потоков или чего-то еще, на самом деле. Насколько я могу судить, я не налагал никаких ограничений на то, что должна содержать защита аргумента использования.
Пример: поток, в котором объект проходит через разные состояния, и эти состояния (значения) сохраняются для каждого объекта (ключа) на карте. По достижении конечного состояния объект может быть удален с карты (другой вариант — счетчик и лимит).
@JoakimDanielson После этого комментария я надеюсь, что смысл этого вопроса, то есть выяснить, существуют ли мыслимые нетривиальные приложения remove(key, value)
в АТД карты с деталями реализации, определенными в Java, вам ясен. Я знаю как факт, что я регулярно не могу правильно объяснить проблемы, поэтому не стесняйтесь предлагать изменения вопросов, которые соответствуют этому конкретному моему вопросу, кроме, конечно, попытки ответить на вопрос самостоятельно.
@JoakimDanielson Я ценю тот факт, что вы первый, кто предложил реальный пример, но, пожалуйста, опубликуйте ответ вместо комментария, чтобы мы могли обсудить этот ответ в отдельном месте.
Нвм мои комментарии. Я думал, что он удаляет значения, но, прочитав обновление @Dorian и перепроверив документы, я увидел, что он фактически удаляет ключ. Сорри за путаницу.
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)
.
@CaptainTrojan Я добавил набросок примера. Надеюсь, это поможет, не могу придумать ничего более конкретного, чем это.
Отлично, не подумал об этом. Хороший вопрос, спасибо за объяснение.
Вам не нужно включать его, поскольку он поставляется с реализацией по умолчанию.