Functional
Stream: 中間操作は終端操作まで評価されない
map は Stream を組み立てただけでは実行されず、toList のような終端操作で初めて評価されます。
SourceLazyStreams.java
Java 21
package examples.stream;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
public final class LazyStreams {
private LazyStreams() {}
public static Stream<Integer> doubled(List<Integer> values, AtomicInteger mapCalls) {
return values.stream()
.map(
value -> {
mapCalls.incrementAndGet();
return value * 2;
});
}
}TestLazyStreamsTest.java
Java 21
package examples.stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
class LazyStreamsTest {
@Test
void Streamは終端操作までmapを評価しない() {
var mapCalls = new AtomicInteger();
var stream = LazyStreams.doubled(List.of(1, 2), mapCalls);
assertEquals(0, mapCalls.get());
assertEquals(List.of(2, 4), stream.toList());
assertEquals(2, mapCalls.get());
}
}01Assertion
このテストで確認できること
- Stream を生成した時点では map の処理は一度も走らない
- toList の実行後に各要素の map が評価される
Stream は遅延評価です。副作用のある処理を中間操作へ置くと、いつ実行されるかを終端操作に依存します。
OBSERVED RESULT
before toList: map calls → 0
after toList: map calls → 2