使用方法"/>
java if函数的使用方法
java - 如何使用新的computeIfAbsent函数?
我非常想使用MapputeIfAbsent,但是因为lambdas在本科课程中已经太长了。
几乎直接来自文档:它给出了一个旧方法的例子:
Map whoLetDogsOut = new ConcurrentHashMap<>();
String key = "snoop";
if (whoLetDogsOut.get(key) == null) {
Boolean isLetOut = tryToLetOut(key);
if (isLetOut != null)
map.putIfAbsent(key, isLetOut);
}
而新的方式:
mapputeIfAbsent(key, k -> new Value(f(k)));
但在他们的例子中,我认为我并没有“得到它”。 我如何转换代码以使用新的lambda表达方式?
5个解决方案
87 votes
最近我也玩这种方法。 我写了一个memoized算法来计算Fibonacci数,这可以作为如何使用该方法的另一个例子。
我们可以从定义一个地图并将其中的值放入基本情况开始,即computeIfAbsent和fibonacci(1):
private static Map memo = new HashMap<>();
static {
memo.put(0,0L); //fibonacci(0)
memo.put(1,1L); //fibonacci(1)
}
对于归纳步骤,我们所要做的就是重新定义我们的Fibonacci函数,如下所示:
public static long fibonacci(int x) {
return memoputeIfAbsent(x, n -> fibonacci(n-2) + fibonacci(n-1));
}
如您所见,方法computeIfAbsent将使用所提供的lambda表达式来计算当地图中不存在该数字时的斐波纳契数。 这代表了对传统的树递归算法的显着改进。
Edwin Dalorzo answered 2019-05-24T09:58:18Z
71 votes
假设您有以下代码:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Test {
public static void main(String[] s) {
Map whoLetDogsOut = new ConcurrentHashMap<>();
whoLetDogsOutputeIfAbsent("snoop", k -> f(k));
whoLetDogsOutputeIfAbsent("snoop", k -> f(k));
}
static boolean f(String s) {
System.out.println("creating a value for \""+s+'"');
return s.isEmpty();
}
}
然后,您将看到消息whoLetDogsOutputeIfAbsent("snoop", key -> tryToLetOut(key));正好在第二次调用k时已经存在该键的值。 lambda表达式whoLetDogsOutputeIfAbsent("snoop", MyClass::tryToLetOut);中的key只是键的一个placeolder(参数),映射将传递给lambda以计算该值。 因此,在示例中,密钥被传递给函数调用。
或者你可以编写:whoLetDogsOutputeIfAbsent("snoop", key -> tryToLetOut(key));来实现没有辅助方法的相同结果(但是你不会看到调试输出)。 甚至更简单,因为它是您可以编写的现有方法的简单委派:k此委派不需要编写任何参数。
为了更接近您的问题中的示例,您可以将其写为whoLetDogsOutputeIfAbsent("snoop", key -> tryToLetOut(key));(无论您是将参数命名为k还是key都无关紧要)。 如果tryToLetOut是static或whoLetDogsOutputeIfAbsent("snoop", this::tryToLetOut);,如果tryToLetOut是实例方法,则将其写为whoLetDogsOutputeIfAbsent("snoop", MyClass::tryToLetOut);。
Holger answered 2019-05-24T09:57:30Z
26 votes
另一个例子。 构建复杂的地图地图时,computeIfAbsent()方法可替代地图的get()方法。 通过将computeIfAbsent()调用链接在一起,可以通过提供的lambda表达式即时构建丢失的容器:
// Stores regional movie ratings
Map>> regionalMovieRatings = new TreeMap<>();
// This will throw NullPointerException!
regionalMovieRatings.get("New York").get(5).add("Boyhood");
// This will work
regionalMovieRatings
puteIfAbsent("New York", region -> new TreeMap<>())
puteIfAbsent(5, rating -> new TreeSet<>())
.add("Boyhood");
hexabc answered 2019-05-24T09:58:45Z
15 votes
如果您想在不使用guava库的情况下创建Multimap,这非常有用([.0/api/docs/com/google/common/collect/Multimap.html]]
例如:如果您要存储为特定主题注册的学生列表。使用jdk库的常规解决方案是
Map> studentListSubjectWise = new TreeMap<>();
Listlis = studentListSubjectWise.get("a");
if(lis == null) {
lis = new ArrayList<>();
}
lis.add("John");
//continue....
由于它有一些样板代码,人们倾向于使用番石榴Multimap。
使用MapputeIfAbsent,我们可以在没有番石榴Multimap的单行中编写如下。
studentListSubjectWiseputeIfAbsent("a", (x -> new ArrayList<>())).add("John");
斯图尔特马克斯&amp; Brian Goetz对此进行了很好的讨论[=9uTVXxJjuco]
nantitv answered 2019-05-24T09:59:44Z
-9 votes
使用computeIfAbsent()和简单的put()get()没有区别
地图的功能。 换句话说,您可以用这种方式重写您的功能
for (char ch : input){
Integer value;
if(countMap.containsKey(ch)){
value = countMap.get(ch);
value++;
countMap.put(ch, value);
}
else{
value = 1;
countMap.put(ch, value);
}
}
Baimyrza Shamyr answered 2019-05-24T10:00:21Z
更多推荐
java if函数的使用方法
发布评论