java8过滤,了解java 8流的过滤方法

本文介绍了Java 8中Stream的懒惰求值特性,通过一个例子展示了当使用filter方法连续过滤时,Stream并不会遍历所有元素,而是仅计算通过所有条件的元素。这种行为是因为Stream在实际计算结果前不会计算所有中间步骤,这有助于提高效率。理解这一点对于高效使用Java 8的Stream API至关重要。
摘要由CSDN通过智能技术生成

I recently learned about Streams in Java 8 and saw this example:

IntStream stream = IntStream.range(1, 20);

Now, let's say that we want to find the first number that's divisable both by 3 and a 5. We'd probably filter twice and findFirst as follows:

OptionalInt result = stream.filter(x -> x % 3 == 0)

.filter(x -> x % 5 == 0)

.findFirst();

That's all sounds pretty reasonable. The surprising part came when I tried to do this:

OptionalInt result = stream.filter(x -> {System.out.println(x); return x % 3 == 0;})

.filter(x -> {System.out.println(x); return x % 5 == 0;})

.findFirst();

System.out.println(result.getAsInt());

I expected to get something like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 and then: 3 6 9 12 15 18. Because we first iterate over all the the numbers between 1 to 20, filter out only those that are divisable by 3 and then iterate this new Stream and find those that are divisable by 5.

But instead I got this output: 1 2 3 3 4 5 6 6 7 8 9 9 10 11 12 12 13 14 15 15 15

It looks like it doesn't go over all the numbers. Moreover, it looks like it checks x % 5 == 0 only for those numbers that are divisable by 3.

I don't understand how come it doesn't iterate over all of the numbers.

解决方案

Well, the thing to understand about streams is that, unlike lists, they don't (necessarily) hold all the items but rather compute each item at a time (lazy evaluation).

It means that when you did IntStream stream = IntStream.range(1, 20); you didn't actually create a collection with 20 items. You created a dynamically computed collection. Each call to this stream's next will compute the next item. The rest of the items are still "not there" (sort of speaking).

Same goes for the filter.

When you add the filter that's checking division by 3 you'll get a new stream that's combined of 2 computations - the first one returns the numbers from 1 until it gets to 20, the second computation returns the numbers that are divided by 3. It's important to understand that each time only the first item is calculated. That's why when you added the check for division by 5 it only worked on those items that were divisible by 3. Same goes as to why the printing stopped at 15. The findFirst method returns the first number that passes all 3 computations (the 1-20 range computation, the division by 3 computation and the division by 5 computation).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值