user7233170
user7233170

Reputation: 71

About processing intermediate operations in a single pass?

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

Answers (2)

Eugene
Eugene

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

Tanmay Patil
Tanmay Patil

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

Related Questions