Java8foreach仅适用于某些应用程序?
请不要使用“如果”语句,除非您正在解释为什么没有“如果”语句是不可能的。 我在看我能在多大程度上只在溪流上运行。我有一个讨厌的问题:Java8foreach仅适用于某些应用程序?,java,java-8,java-stream,Java,Java 8,Java Stream,请不要使用“如果”语句,除非您正在解释为什么没有“如果”语句是不可能的。 我在看我能在多大程度上只在溪流上运行。我有一个讨厌的问题: List<Cube> revised = cubes.filter(p) .map(c -> f(c)) .map(c -> { if(c.prop()) { c.addComment(comment); } return c; })
List<Cube> revised =
cubes.filter(p)
.map(c -> f(c))
.map(c -> {
if(c.prop()) {
c.addComment(comment);
}
return c;
})
.collect(Collectors.toList());
修改列表=
立方体.过滤器(p)
.地图(c->f(c))
.map(c->{
if(c.prop()){
c、 添加评论(评论);
}
返回c;
})
.collect(Collectors.toList());
关于如何在没有“如果”的情况下做到这一点,我的最佳想法是
列表修订=
立方体.过滤器(p)
.map(c->f(c));
修订过的
.filter(多维数据集::prop)
.forEach(c->c.addComment(comment));//还可以映射吗
有没有一种方法只在一个链中实现这一点?如果是这样,分支基本上必须发生在流中。对于某些(谓词,lambda)这样的方法是可行的
不想“滚我自己的”任何东西。我可以使用“如果”,但我正在尝试学习函数式的表达方式。当您使用
peek
时,没有必要使用返回相同元素的map
。以下代码通过使用短路操作员“欺骗”:
cubes.filter(p)
.map(c -> f(c))
.peek(c -> c.prop() && c.addComment(comment))
我认为使用Optional的“现代”方式可读性要差得多:
cubes.filter(p)
.map(c -> f(c))
.peek(c -> Optional.of(c).filter(Cube::prop).ifPresent(c -> c.addComment(comment)))
您可以通过以下方式实现某些功能:
public static <T> T forSome(T c, Predicate<T> condition, Consumer<T> extraBehaviour) {
if (condition.test(c)) {
extraBehaviour.accept(c);
}
return c;
}
印刷品:
- 约翰:通过了
- 安迪:通过了
- 玛丽:通过了
- 简:是假的
Cube::prop“tee”您的流,可能会有所帮助。这需要拆分和合并流—这是Java流库所不做的。但是,其他库也支持它。f(c)
返回什么?假设addComment
返回boolean
不是可选的.of(c)样式的问题?它似乎嵌套了一个lambda而不是chain one,即第一个“c”被第二个“c”遮挡,即使逻辑上它们是相同的。@djechlin:当然,当范围中已经有一个c
时,声明一个新的c
是不起作用的。您必须使用不同的名称。
public static <T> T forSome(T c, Predicate<T> condition, Consumer<T> extraBehaviour) {
if (condition.test(c)) {
extraBehaviour.accept(c);
}
return c;
}
List<Cube> revised = cubes.stream().filter(p)
.map(c -> f(c))
.map(c -> forSome(c, Cube::prop, cube -> cube.addComment("my comment 2")))
.collect(Collectors.toList());
class StudentExam {
private final String studentName;
private final List<Character> answers;
private boolean passed = false;
StudentExam(String studentName, List<Character> answers) {
this.studentName = studentName;
this.answers = answers;
}
public void markAsPassed() {
this.passed = true;
}
public boolean isPassed() {
return passed;
}
public Character getAnswer(int index) {
return answers.get(index);
}
public String getStudentName() {
return studentName;
}
}
List<StudentExam> results = asList(
new StudentExam("John", asList(new Character[] {'A', 'B'})),
new StudentExam("Andy", asList(new Character[] {'A', 'C'})),
new StudentExam("Mary", asList(new Character[] {'B', 'B'})),
new StudentExam("Jane", asList(new Character[] {'C', 'D'}))
);
results.stream()
.map(examResult -> forSome(
examResult,
er -> er.getAnswer(0).equals('A') || er.getAnswer(1).equals('B'),
StudentExam::markAsPassed))
.forEach(studentExam ->
studentExam.getStudentName() + " passed: " + studentExam.isPassed()));