Code
This was taken from the book "Modern Java in Action":
private static class WordCounter {
private final int counter;
private final boolean lastSpace;
public WordCounter(int counter, boolean lastSpace) {
this.counter = counter;
this.lastSpace = lastSpace;
}
public WordCount.WordCounter accumulate(Character c) {
if (Character.isWhitespace(c)) {
return lastSpace ? this : new WordCount.WordCounter(counter, true);
}
else {
return lastSpace ? new WordCount.WordCounter(counter + 1, false) : this;
}
}
public WordCount.WordCounter combine(WordCount.WordCounter wordCounter) {
return new WordCount.WordCounter(counter + wordCounter.counter, wordCounter.lastSpace);
}
public int getCounter() {
return counter;
}
}
Accumulator as method accepting only 1 parameter
The accumulate method of the WordCounter class is being used in reduce
step like in this snippet:
private static int countWords(Stream<Character> stream) {
WordCounter wordCounter = stream.reduce(
new WordCounter(0, true),
WordCounter::accumulate,
WordCounter::combine
);
return wordCounter.getCounter();
}
Accumulator as lambda accepting 2 parameters
Normally, when we create an accumulate method, we usually have two parameters passed in the lambda. Like in this test (subtotal, element)
:
// Given
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
// When
int result = numbers
.stream()
.reduce(0, (subtotal, element) -> subtotal + element);
// Then
assertThat(result).isEqualTo(21);
Questions
How does accumulation work when the method from WordCounter class is used?
How to (visually) illustrate the accumulation with the method for a single parameter?