.Put () в .getOrDefault () вычисляется каждый раз? - PullRequest
1 голос
/ 25 апреля 2020
Map<String, Ob> map = new HashMap<>();
String[] arr = {"a", "a", "c", "c"};

int count = 1;
for (String a: arr) {
    System.out.println("putting \"" + a + "\" in map");
    System.out.println(map.getOrDefault(a, map.put(a, new Ob(a + "" + count++))));
    System.out.println("map: " + map);
}

Ob - это очень простой класс:

class Ob {
    String o;
    Ob (String message) { o = message; }

    @Override
    public String toString() { return o; }
}

Отпечатки:

putting "a" in map
a1
map: {a=a1}
putting "a" in map
a2                        
map: {a=a2}                     -> Why is the value replaced?
putting "c" in map
c3
map: {a=a2, c=c3}
putting "c" in map
c4
map: {a=a2, c=c4}               -> Why is the value replaced?

Я думал, что для второго a это просто вызовет значение a1 и вернитесь, потому что a уже существует на карте. Но он создал объект в .put().

Похоже, что default в getOrDefault вычислено, даже если ключ существует. Как я могу написать это кратко, не создавая новые объекты, когда ключ уже существует?

Я, конечно, могу написать это с if/else, но я хочу посмотреть, можно ли исправить текущий подход.

Ответы [ 2 ]

3 голосов
/ 25 апреля 2020

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

Map имеет метод computeIfAbsent, который делает то, что вы хотите, здесь:

map.computeIfAbsent(a, k -> new Ob(k + "" + count++));

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

1 голос
/ 25 апреля 2020

Да.

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

Вы можете переосмыслить свои логи c.

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