如何使用lambda java8简化以下代码? 我是lambda的新手并且还在学习它。
public boolean isValuePresent(String id, Optional<String> value) {
ClassConfig config = configStorage.getConfig();
Map<String, FeatureClass> map = config.getConfigMap();
if (map.containsKey(id)) {
Set<String> set = map.get(id).getset();
if (!set.isEmpty()) {
if (value.isPresent()) {
if (set.contains(value.get())) {
log.info(String.format("value present for id %s", id));
return true;
}
}
}
}
return false;
}
答案 0 :(得分:2)
您已经完成了外部循环,并想使用流API,这使我们能够专注于内部循环逻辑。
在流中,共有3个部分。一个是源,这里是map.keySet(),第二个是一系列中间操作,即filter(),map()等。所有操作都创建新流并且不更改源,第三个是终端操作,即forEach(), collect(),anyMatch(),allMatch()等...
流具有耗材和惰性执行属性。这意味着在我们使用任何终止操作之前,流尚未执行。而且一旦应用了终止运算符,流就已经消耗了,无法再消耗了。
boolean retval = map.keySet().stream()
.filter(x -> x.equals(id))
.filter(x -> !map.get(x).getset().isEmpty())
.filter(x -> value.isPresent())
.anyMatch(x -> map.get(x).getset().contains(value.get()));
来自Java8的Collection API实现了流接口。 Map不是集合API的一部分,因此我们使用map.keySet()并应用stream()来获取集合。这成为了我们的来源。 过滤器运算采用任何布尔表达式,这里我们将映射键与id参数进行比较,并检查值param是否存在。 anyMatch是终止操作,如果map中的任何键都满足上述条件,则它将返回true。
答案 1 :(得分:0)
总之 - 没有。这个代码可以用lambdas本身解决,没有任何错误或复杂。你应该做的是检查这段代码实际上做了什么,并从那里简化它。
我接受它,如果你不能改变isValuePresent
的签名,那么做这样的事情:
boolean isValuePresent(String id, Optional<String> option) {
if (!option.isPresent()) { // this already saves us loading the config if we've got no value to check against
return false;
}
FeatureClass features = configStorage.getConfig().getConfigMap().get(id);
if (features == null) { // replaces containsKey().get() with one call. It is hardly an improvement, just my stylistic choice
return false;
}
String value = option.get();
if (features.getset().contains(value) { // we actually have no need to check if set is empty or not, we rather have it handle that itself
log.info(String.format("value present for id %s", id));
return true;
}
return false;
}
或者,如果你可以改变签名,我认为最好有这样的东西:
boolean isValuePresent(String id, String value) {
FeatureClass features = configStorage.getConfig().getConfigMap().get(id);
if (features == null) {
return false;
}
if (features.getset().contains(value)) {
log.info(<snip>);
return true;
}
return false;
}
并称之为:
String id = loadId();
Optional<String> myValue = loadMyValue(id);
return myValue.map(value -> Checker.isValuePresent(id, value)).orElse(false);
正如你所看到的,没有lambda,因为没有lambdas - 在这里我们不需要改变我们的行为,这种方法中没有可能从外部插入的策略。
现在,关于为什么我选择在参数中没有Optional:
String
形式,则在调用您的方法之前,不需要将它包装在无用的Optional
中。Optional
作为方法参数类型看起来很丑陋,因为该类设计用作返回值,并且除isPresent()
和get()
之外不提供更多参数类型。当它被用作返回值时,将其与大量受控值提取方法进行比较(仅举几例,orElse
,orElseGet
,map
,flatMap
甚至更多进入Java 9)。java.util.Optional
不是Serializable
,它结束了通过远程接口调用您的方法(当然,这意味着您关心通过远程接口调用它)。答案 2 :(得分:-1)
此代码是否适合您?
ModelName.pluck(:sunday).inject(:|)
我也试过这个,但是在lambda中返回函数不能工作:/
for(Map.Entry<String, String> entry : map.entrySet()) {
if(entry.getKey().equals(id)) {
if (value.isPresent() && entry.getValue().equals(value.get())) {
System.out.println(String.format("value present for id %s", id));
return true;
}
}
}
return false;
修改强> 我找到了办法^^
map.forEach((key, mapValue) -> {
if(key.equals(id)) {
if (value.isPresent() && mapValue.equals(value.get())) {
System.out.println(String.format("value present for id %s", id));
return true; //doesn't work -> Unexpected return value
}
}
});