Есть ли более краткий способ сделать это в Java 8 - манипулирование картой - PullRequest
3 голосов
/ 09 июля 2019

Очень распространенная операция на картах коллекций - создать новую коллекцию с начальным значением, когда ключ отсутствует, или, если ключ присутствует, выполнить некоторую функцию в существующей коллекции.Например, Map<String, Set<Integer>>, если ключа нет, создайте набор с начальным значением 1. Если ключ есть, добавьте значение map.size () + 1 в набор (или замените эту функцию нанекоторые другие простые однострочные операции).В Java 7 это просто с if / else, но довольно многословно.Я могу только придумать код ниже для Java 8, который не намного лучше (на самом деле хуже из-за большего количества строк кода).Есть ли способ сделать это более кратким?

public void process(Map<String, Set<Integer>> m, String key) {
    m.compute(key, (k, v) -> {
        if (v == null) {
            v = new HashSet<>();
            v.add(1);
            return v;
        } else {
            v.add(v.size() + 1);
            return v;
        }
    });
}

Ответы [ 2 ]

3 голосов
/ 09 июля 2019

Вот еще одна альтернатива:

Set<Integer> set = m.computeIfAbsent (key , k -> new HashSet<> ());
set.add(set.size() + 1);

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

3 голосов
/ 09 июля 2019

К сожалению, не однострочный, но он делает свое волшебство и также более читабелен (недостаток: он создает новый HashSet<>() каждый раз)

m.putIfAbsent(key, new HashSet<>());
// Solution 1 :
m.compute(key, (k, v) -> {v.add(v.size() + 1); return v;});
// Solution 2 :
Set<Integer> s = m.get(key);
s.add(s.size() + 1);

Или как предложено @Thilo и вдохновлено @ Eran

m.computeIfAbsent(key, k -> new HashSet<>()).add(m.get(key).size() + 1);

Один вкладыш возможен, потому что он возвращает значение, рассчитанное им, как указано в javadoc

Если указанный ключ еще не связан со значением (или сопоставлен со значением NULL), попытается вычислить его значение, используя заданную функцию сопоставления, и вводит его в эту карту, если только не NULL.

Существует даже аналогичный пример в javadoc

map.computeIfAbsent (ключ, k -> новый HashSet ()). Add (v);

Небольшой компромисс лайнера - дополнительный вызов m.get(key), который не происходит с решением @ Eran

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...