Suponha que você tenha o seguinte código:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
public static void main(String[] s) {
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
whoLetDogsOut.computeIfAbsent("snoop", k -> f(k));
}
static boolean f(String s) {
System.out.println("creating a value for \""+s+'"');
return s.isEmpty();
}
}
Então você verá a mensagem creating a value for "snoop"
exatamente uma vez, pois na segunda invocação de computeIfAbsent
já existe um valor para aquela chave. O k
na expressão lambda k -> f(k)
é apenas um placeolder (parâmetro) para a chave que o mapa passará para seu lambda para calcular o valor. Portanto, no exemplo, a chave é passada para a invocação da função.
Alternativamente, você pode escrever: whoLetDogsOut.computeIfAbsent("snoop", k -> k.isEmpty());
para obter o mesmo resultado sem um método auxiliar (mas você não verá a saída de depuração então). E ainda mais simples, pois é uma delegação simples para um método existente que você pode escrever: whoLetDogsOut.computeIfAbsent("snoop", String::isEmpty);
Esta delegação não precisa de nenhum parâmetro para ser escrito.
Para ficar mais próximo do exemplo em sua pergunta, você pode escrever como whoLetDogsOut.computeIfAbsent("snoop", key -> tryToLetOut(key));
(não importa se você nomeia o parâmetro k
ou key
). Ou escreva como whoLetDogsOut.computeIfAbsent("snoop", MyClass::tryToLetOut);
se tryToLetOut
fosse static
ou whoLetDogsOut.computeIfAbsent("snoop", this::tryToLetOut);
se tryToLetOut
fosse um método de instância.