You can implement your forSome function as follows:
public static <T> T forSome(T c, Predicate<T> condition, Consumer<T> extraBehaviour) { if (condition.test(c)) { extraBehaviour.accept(c); } return c; }
How can you use the map operator to insert it into the stream:
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());
To give another use case, we can take the following example:
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'})) );
Now we can, if the correct answers are "A" and "B", than we can pass through the objects and set the corresponding exam status.
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()));
prints:
- John: the truth has passed
- Andy: the truth has passed
- Maria: the truth has passed
- Jane: gone lies
source share