不小心重用了流
我敢打赌,每人至少都会犯一次这样的错误。就像现有的这些“流”(比如说InputStream),你也只能对它们消费一次。下面的代码是无法工作的:
IntStream stream = IntStream.of(1, 2);
stream.forEach(System.out::println);
// That was fun! Let's do it again!
stream.forEach(System.out::println);
你会碰到一个这样的错误:
java.lang.IllegalStateException:
stream has already been operated upon or closed
因此使用流的时候应当格外注意。它只能消费一次。
不小心创建了一个”无限"流
你可能一不留神就创建了一个无限流。就拿下面这个例子来说:
IntStream.iterate(0, i -> i + 1)
.forEach(System.out::println);
流的问题就在于它有可能是无限的,如果你的确是这样设计的话。唯一的问题就是,这并不是你真正想要的。因此,你得确保每次都给流提供一个适当的大小限制:
// That's better
IntStream.iterate(0, i -> i + 1)
.limit(10)
.forEach(System.out::println);
不小心创建了一个“隐藏的”无限流
这个话题是说不完的。你可能一不小心就真的创建了一个无限流。比如说下面的这个:
IntStream.iterate(0, i -> ( i + 1 ) % 2)
.distinct()
.limit(10)
.forEach(System.out::println);
这样做的结果是:
我们生成了0和1的交替数列
然后只保留不同的数值,比如说,一个0和一个1
然后再将流的大小限制为10
最后对流进行消费
好吧,这个distinct()操作它并不知道iterate()所调用的这个函数生成的只有两个不同的值。它觉得可能还会有别的值。因此它会不停地从流中消费新的值,而这个limit(10)永远也不会被调用到。不幸的是,你的应用程序会崩掉。
不小心创建了一个”隐藏”的并行无限流
我还是想继续提醒下你,你可能真的一不小心就消费了一个无限流。假设你认为distinct()操作是会并行执行的。那你可能会这么写:
IntStream.iterate(0, i -> ( i + 1 ) % 2)
.parallel()
.distinct()
.limit(10)
.forEach(System.out::println);