否"如果"请说明,除非您解释为什么没有它就无法做到。
我看到我只能在溪流上运行多远。我有这种麻烦:
List<Cube> revised =
cubes.filter(p)
.map(c -> f(c))
.map(c -> {
if(c.prop()) {
c.addComment(comment);
}
return c;
})
.collect(Collectors.toList());
我最好的想法是如何在没有&#34; if&#34;是
List<Cube> revised =
cubes.filter(p)
.map(c -> f(c));
revised
.filter(Cube::prop)
.forEach(c -> c.addComment(comment)); // can also map still
有没有办法只在一个链中做到这一点?如果是这样,分支基本上必须在流中发生。像forSome(predicate, lambda)
这样的方法可行。
不想&#34;滚动我自己&#34;任何东西。我可以使用&#34; if&#34;但我试图了解表达性的功能风格。
答案 0 :(得分:3)
当您拥有map
时,无需使用返回相同元素的peek
。以下代码&#34;作弊&#34;通过使用短路运营商:
cubes.filter(p)
.map(c -> f(c))
.peek(c -> c.prop() && c.addComment(comment))
我认为&#34;现代&#34;使用Optional的方式可读性差得多:
cubes.filter(p)
.map(c -> f(c))
.peek(c -> Optional.of(c).filter(Cube::prop).ifPresent(c -> c.addComment(comment)))
答案 1 :(得分:1)
您可以通过以下方式实施forSome
功能:
public static <T> T forSome(T c, Predicate<T> condition, Consumer<T> extraBehaviour) {
if (condition.test(c)) {
extraBehaviour.accept(c);
}
return c;
}
您可以使用map运算符将其注入流中:
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'}))
);
现在我们可以正确答案是&#39; A&#39;和&#39; B&#39;比我们可以流过对象并设置适当的考试状态。
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()));
打印: