Reputation: 71
take the following code:
// 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();
running the code above multiple times gives always the following output :
filtring 300
filtring 1000
mapping 1000
filtring 400
filtring 710
mapping 710
filtring 700
mapping 700
filtring 950
mapping 950
I don't undrestand this output. someone can give me an explanation about this result. I have expected this output:
filtring 300
filtring 1000
filtring 400
filtring 710
filtring 700
filtring 950
mapping 1000
mapping 710
mapping 700
mapping 950
Upvotes: 1
Views: 65
Reputation: 120848
This is expected. The entire pipeline is executed (in a lazy way - that is why you only see the first filtering 300 without mapping afterwards) on an element at a time.
You can think about it like this: the first element is first filtered, then mapped; then the second one is filtered and then mapped. If filtering returns false
, there is no need to execute the mapping, the result will be omitted anyway (that's why it is lazy).
This is pretty basic stuff when it comes to streams actually.
By the way, that seems to be an example from “java-8 in action” if I’m not mistaken and that book explains these basic things pretty good. Be sure to read it again (and again if needed).
Upvotes: 3
Reputation: 7057
In the following expression
transaction.stream().filter(conditionPredicate).map(mapperFunction).count();
The type of returned object after each method call is
List<Transaction> => Stream<Transaction> => Stream<Transaction> => Stream<Integer> => long
The Stream
library is mostly implemented lazily. This means that all lambdas in the operation pipeline are applied on the first element, then all lambdas on the second element and so on. Intermediate collections (streams) are not stored at all.
Hope this helps.
Upvotes: 3