错误:不兼容类型:意外返回值:Java 8

错误:不兼容类型:意外返回值:Java 8,java,foreach,java-8,java-stream,Java,Foreach,Java 8,Java Stream,我写了一个简单的方法,返回布尔值 private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs){ if(studentConfigs != null) { studentConfigs.forEach(studentConfig -> { if(studentConfig.action()

我写了一个简单的方法,返回布尔值

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs){
       if(studentConfigs != null)
        {
            studentConfigs.forEach(studentConfig -> {
                if(studentConfig.action() == null || !studentConfig.action().equals(Action.DELETE)) {
                    return true;
                }
            });
        }
        return false;
    }

我的代码有什么问题?

传递给
forEach
的lambda表达式不应该有返回值

如果输入
集合
的任何元素满足以下条件,则您可能希望返回
true

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs){
    if(studentConfigs != null) {
        if (studentConfigs.stream().anyMatch(sc -> sc.action() == null || !sc.action().equals(Action.DELETE))) {
            return true;
        }
    }
    return false;
}


或者,使用Java9和更高版本,您可以使用并更新为:

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs) {
    return Stream.ofNullable(studentConfigs)
            .flatMap(Collection::stream)
            .anyMatch(studentConfig -> studentConfig.action() == null || !studentConfig.action().equals(Action.DELETE));
}
private boolean isActionAvailable(集合studentConfigs){
可调用的返回流(studentConfigs)
.flatMap(集合::流)
.anyMatch(studentConfig->studentConfig.action()==null | | |!studentConfig.action().equals(action.DELETE));
}

我不建议您在这里使用流API。看看foreach的
版本有多清晰和简单:

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigurations) {
    if(studentConfigurations == null) {
        return false;
    }

    for (StudentConfiguration configuration : studentConfigurations) {
        if (!Action.DELETE.equals(configuration.action())) {
            return true;
        }
    }

    return false;
}
private boolean isActionAvailable(集合studentConfigurations){
if(studentConfigurations==null){
返回false;
}
for(StudentConfiguration配置:studentConfigurations){
如果(!Action.DELETE.equals(configuration.Action())){
返回true;
}
}
返回false;
}
否则,如果你是一个狂热的人

private boolean isActionAvailable(Collection<StudentConfiguration> configs) {
    return configs != null &&
           configs.stream()
                  .map(StudentConfiguration::action)
                  .anyMatch(Predicate.isEqual​(Action.DELETE).negate()));
}
private boolean isActionAvailable(集合配置){
返回配置!=null&&
configs.stream()
.map(StudentConfiguration::action)
.anyMatch(谓词.isEqual​(Action.DELETE).negate());
}

lambda中的
return
语句将终止该lambda,而不是
isActionAvailable()
方法。因此,推断出的lambda类型现在是错误的,因为
forEach
需要
消费者


查看其他答案以了解如何解决该问题。

这是forEach()方法的签名
forEach(消费者为什么不是简单的增强forloop?何时选择一个?Lukegarigan enhanced for loop也可以。至于选择哪一个,我会选择一个更易于阅读的(以及其他可能阅读您的代码的开发人员)。我认为在本例中使用
anyMatch
更好地表达了该方法的作用,即查找输入集合的任何元素是否满足某些条件。@Lukegarigan Java是一种不断发展的语言。高阶函数正在按其方式运行。我建议您接受它们,而不是离开behind@LukEgarigan“我想这只是因为我没有像我可能应该的那样经常使用它。”是的,差不多。这是Java的未来,所以你只会看到越来越多的高阶函数。@Lukegarigan嗯,你会使用
collection.contains(obj)
而不是在集合上循环测试每个元素的相等性,不是吗?所以
collection.stream()。anyMatch(condition)
只是这个想法的概括,当条件比简单的相等性更复杂时。是否
stream.ofNullable(studentConfigs).flatMap(collection::stream)是有争议的…
studentConfigs!=null&&studentConfigs.stream()简单…
@Holger这里的simpler你指的是可读性方面还是性能?可读性我相信是基于观点的,我觉得现在很容易阅读,也许有时候我不会。我写评论的时候只是指可读性,但现在你问到了,
flatMap
缺乏惰性的问题仍然存在于Java9中,这将是不使用Java10之前的变体的原因。但在最近的版本中,我不会考虑任何剩余的微小性能差异。
private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs) {
    return Stream.ofNullable(studentConfigs)
            .flatMap(Collection::stream)
            .anyMatch(studentConfig -> studentConfig.action() == null || !studentConfig.action().equals(Action.DELETE));
}
private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigurations) {
    if(studentConfigurations == null) {
        return false;
    }

    for (StudentConfiguration configuration : studentConfigurations) {
        if (!Action.DELETE.equals(configuration.action())) {
            return true;
        }
    }

    return false;
}
private boolean isActionAvailable(Collection<StudentConfiguration> configs) {
    return configs != null &&
           configs.stream()
                  .map(StudentConfiguration::action)
                  .anyMatch(Predicate.isEqual​(Action.DELETE).negate()));
}
 error: incompatible types: unexpected return value
            studentConfigs.forEach(studentConfig ->