如何使用新的 computeIfAbsent 函数? [英] How do I use the new computeIfAbsent function?
问题描述
我非常想使用Map.computeIfAbsent 但距离本科生的 lambdas 已经太久了.
I very much want to use Map.computeIfAbsent but it has been too long since lambdas in undergrad.
几乎直接来自文档:它给出了一个旧的做事方式的例子:
Almost directly from the docs: it gives an example of the old way to do things:
Map<String, Boolean> whoLetDogsOut = new ConcurrentHashMap<>();
String key = "snoop";
if (whoLetDogsOut.get(key) == null) {
Boolean isLetOut = tryToLetOut(key);
if (isLetOut != null)
map.putIfAbsent(key, isLetOut);
}
还有新的方式:
map.computeIfAbsent(key, k -> new Value(f(k)));
但在他们的例子中,我认为我不太明白".我将如何转换代码以使用新的 lambda 表达方式?
But in their example, I think I'm not quite "getting it." How would I transform the code to use the new lambda way of expressing this?
推荐答案
假设你有以下代码:
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();
}
}
然后您将看到消息 creating a value for "snoop"
恰好一次,因为在第二次调用 computeIfAbsent
时,该键已经有一个值.lambda 表达式中的 k
k ->f(k)
只是映射将传递给您的 lambda 以计算值的键的占位符(参数).所以在这个例子中,key 被传递给了函数调用.
Then you will see the message creating a value for "snoop"
exactly once as on the second invocation of computeIfAbsent
there is already a value for that key. The k
in the lambda expression k -> f(k)
is just a placeolder (parameter) for the key which the map will pass to your lambda for computing the value. So in the example the key is passed to the function invocation.
或者,您可以编写:whoLetDogsOut.computeIfAbsent("snoop", k -> k.isEmpty());
以在没有辅助方法的情况下实现相同的结果(但您不会看到然后调试输出).甚至更简单,因为它是对现有方法的简单委托,您可以编写: whoLetDogsOut.computeIfAbsent("snoop", String::isEmpty);
该委托不需要编写任何参数.
Alternatively you could write: whoLetDogsOut.computeIfAbsent("snoop", k -> k.isEmpty());
to achieve the same result without a helper method (but you won’t see the debugging output then). And even simpler, as it is a simple delegation to an existing method you could write: whoLetDogsOut.computeIfAbsent("snoop", String::isEmpty);
This delegation does not need any parameters to be written.
为了更接近您问题中的示例,您可以将其写为 whoLetDogsOut.computeIfAbsent("snoop", key -> tryToLetOut(key));
(无论是否您将参数命名为 k
或 key
).或者写成 whoLetDogsOut.computeIfAbsent("snoop", MyClass::tryToLetOut);
如果 tryToLetOut
是 static
或 whoLetDogsOut.computeIfAbsent("snoop", this::tryToLetOut);
如果 tryToLetOut
是一个实例方法.
To be closer to the example in your question, you could write it as whoLetDogsOut.computeIfAbsent("snoop", key -> tryToLetOut(key));
(it doesn’t matter whether you name the parameter k
or key
). Or write it as whoLetDogsOut.computeIfAbsent("snoop", MyClass::tryToLetOut);
if tryToLetOut
is static
or whoLetDogsOut.computeIfAbsent("snoop", this::tryToLetOut);
if tryToLetOut
is an instance method.
这篇关于如何使用新的 computeIfAbsent 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!