采取以下代码:
// trader (name, city)
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
// transaction(trader, year, value)
List<Transaction> transactions = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950)
);
transactions.stream()
.filter( t -> {
System.out.println("filtring "+t.getValue());
return t.getValue()>=700;
})
.map(t -> {
System.out.println("mapping "+t.getValue());
return t.getValue();
})
.count();
多次运行上面的代码总是给出以下输出:
filtring 300
filtring 1000
mapping 1000
filtring 400
filtring 710
mapping 710
filtring 700
mapping 700
filtring 950
mapping 950
我不会动摇这个输出。有人可以给我一个关于这个结果的解释。我期待这个输出:
filtring 300
filtring 1000
filtring 400
filtring 710
filtring 700
filtring 950
mapping 1000
mapping 710
mapping 700
mapping 950
答案 0 :(得分:3)
这是预期的。整个管道(一个懒惰的方式 - 这就是为什么你一次只能在元素上看到第一个过滤300 而没有后映射的原因)。
你可以这样思考:首先过滤第一个元素,然后映射;然后过滤第二个然后映射。如果过滤返回false
,则不需要执行映射,无论如何都会省略结果(这就是为什么它是懒惰的。)
实际上,当涉及到流时,这是非常基本的东西。
顺便说一句,这似乎是“ java-8 in action ”中的一个例子,如果我没有弄错的话,那本书解释了这些基本的东西。请务必再次阅读(如果需要,请再次阅读)。
答案 1 :(得分:3)
在以下表达式中
transaction.stream().filter(conditionPredicate).map(mapperFunction).count();
每次方法调用后返回的对象的类型是
List<Transaction> => Stream<Transaction> => Stream<Transaction> => Stream<Integer> => long
Stream
库主要是懒惰地实现的。这意味着操作管道中的所有lambda都应用于第一个元素,然后应用于第二个元素上的所有lambdas,依此类推。中间集合(流)根本不存储。
希望这有帮助。