Обход нулевой проверки при заполнении HashMap - PullRequest
0 голосов
/ 22 декабря 2018

При вставке в хэш-карту, всегда ли мне нужно проверять, есть ли нулевое значение, соответствующее вставляемому ключу?

Например, если я хочу отслеживать количество раз символапроисходит в слове, используя hashmap, всегда ли я должен делать:

if(hashMap.containsKey(ch)){
    hashMap.replace(ch, 1+hashMap.get(ch));    
}
else{
    hashMap.put(ch, 1);    
}

Или есть функция, которая может обработать это для меня?

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

Вам не нужно.Map имеет метод merge, который можно использовать для обновления значения:

hashMap.merge(ch, 1, (oldVal, newVal) -> oldVal + newVal);

Что это значит:

  • Если hashMap еще не имеетch, затем добавляется новая запись с ch в качестве ключа и 1 в качестве значения
  • Если hashMap уже имеет запись с ch в качестве ключа, то вызывается последняя функциявычислить значение обновления.В этом случае (oldVal, newVal) -> oldVal + newVal просто добавляет старое значение к новому.

Как указано в в комментарии Энди , вы также можете использовать Map.compute:

int newValue = hashMap.compute(ch, 
      (key, existingVal) -> (existingVal == null) ? 1 : existingVal + 1);
0 голосов
/ 22 декабря 2018

Просто чтобы прояснить, вам не нужно различать, существует ли ключ на карте или нет.Другими словами, вместо использования replace в вашем примере, вы можете использовать put.

Конечно, вам нужно иметь дело с тем, есть ли у вас предварительное значение, которое вам нужно включить вобновленное значение.Как уже отмечали другие, вы можете использовать методы merge или compute.

Однако, если у вас есть причины предпочитать придерживаться put, вот пара идей о том, как структурировать код.

В исходном коде

if(hashMap.containsKey(ch)){
    hashMap.replace(ch, 1+hashMap.get(ch));    
}
else{
    hashMap.put(ch, 1);    
}

вы звоните containsKey и get, оба из которых, по сути, выполняют поиск.Почему поиск выполняется дважды?

Integer count = hashMap.get(ch);
if(count != null){
    hashMap.replace(ch, 1+count);    
}
else{
    hashMap.put(ch, 1);    
}

Вместо использования replace для одного случая и put для другого, вы можете так же легко использовать put для обоих случаев.И вы можете комбинировать случаи:

Integer count = hashMap.get(ch);
if (count == null) {
    count = 0;
}
hashMap.put(ch, count + 1); 

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

// Get the current value.
Integer count = hashMap.get(ch);
if (count == null) {
    // Business logic for initial value.
    count = 0;
}

// Compute the new value (might be a bunch of business logic).
count++;

// Put the new value back.
hashMap.put(ch, count); 
0 голосов
/ 22 декабря 2018

Используйте merge.

hashMap.merge(ch, 1, (left, right) -> left + right);

или используйте ссылку на метод:

 hashMap.merge(ch, 1, Math::addExact);
  • Если указан ключ (ch inв этом случае) еще не связано со значением или связано с нулевым значением, связывает его с заданным ненулевым значением (в данном случае 1).
  • , если указанный ключ связан с ненулевымЗначение NULL затем заменяет ассоциированное значение результатами данной функции переотображения (left, right) -> left + right.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...