I use an InStream.range
with a mapToObj
mapper as a substitute for-loop to initialize a database for a test by creating some records, which then I want to count to verify that the correct number has been created.
I have noticed that the Stream.count
terminal operation returns the correct count, but when I use the count
method from my persistence layer it returns 0
. The mapper callback is not being called and thus no records are created.
Here is a sample that demonstrates the issue:
public class IntStreamTest {
private final List<String> db = new ArrayList<>();
@Test
public void mapToStringAndCount() {
long count = IntStream
.range(1000, 1010)
.mapToObj(this::mapToString)
// .filter(Objects::nonNull)
.count();
Assert.assertEquals(10L, count);
Assert.assertEquals(count, countString());
}
private long countString() {
return db.size();
}
private String mapToString(int i) {
String string = String.format("string-%d", i);
System.out.printf("%s%n", string);
db.add(string);
return string;
}
}
When I use the intermediate operation Stream.filter
after IntStream.mapToObj
everything works fine. Also the the records are created when is use Stream.collect
after IntStream.mapToObj
or IntStream.forEachinstead of
IntStream.mapToObj`.
Why does IntStream
behaves like this?
$ java -version
openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu219.04)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu219.04, mixed mode, sharing)