SS'
SS'

Reputation: 857

Calling method on object in Java 8 stream after collecting

Suppose I have this bit of code:

Map<Consumer, Item> map = myStream.parallel()
        .filter(Objects::nonNull)
        .collect(Collectors.toConcurrentMap(e->e,
                e->e, mergeFunction));

What I want to do is call a method on each object of the stream after collecting is done.

For example,

item.setDate(item.getOneDate());

Before the code done sequentially looped through items, put into a map, and at the very end called a bit of the code like the one above, setting a 'date'.

while(iterator.hasNext()) {
   Item blah = iterator.next();
   ....
   // code for putting into map
   ...
   blah.setDate(blah.getOneDate());
}

Not sure how to do this with Java 8 streams. forEach? peek?

Upvotes: 2

Views: 8014

Answers (3)

Renan Paul Blanco
Renan Paul Blanco

Reputation: 86

I would agree with Jigar Joshi. A map operation is cleaner. And if you have no need for an intermediate object, just return the same one:

myStream.parallelStream()
        .map(i -> { i.setDate(i.getOneDate()); return i; })
        ...

That said, I would avoid mutating objects in the middle of a Stream. It's bad practice.

Upvotes: 0

shmosel
shmosel

Reputation: 50756

This will be controversial, but I would use peek():

myStream.parallel()
        .filter(Objects::nonNull)
        .peek(item -> item.setDate(item.getOneDate()))

IMO, this use case invalidates many of the arguments against using peek() for state modification, since it's essentially side-effect free (assuming elements are no longer accessible from the stream source). It definitely complies with the only strict requirement of non-interference.

Upvotes: 2

Ousmane D.
Ousmane D.

Reputation: 56469

if this must be done after the collect operation, just use forEach:

map.forEach((k, v) -> {...});

if you're only interested in values:

map.values().forEach(item -> {...});

or only keys:

map.keySet().forEach(item -> {...});

Upvotes: 6

Related Questions