2

I've a a stream which I want to partition into smaller parts based on matching Id and then apply some proccessing logic on each of the part/element.

class BigRequest{
String bId;
List<Parts> parts;
//getters and setter here
}

Class Parts{
String pId;
String partId;
//getters and setter here
}

I want to segregate and create a list of Parts of size 10 when the partId of different parts are same.

How to use the filter or reduce or groupingBy function to compare the two elements and put them to a list? I've tried filter like below, doesn't take p1 variable:

big.stream().filter( p -> p.getPartId() == p1.getPartId()) //error

Tried groupingBy like this

big.stream().collect(Collectors.groupingBy(Parts::getPartId) //error

I want to iterate over the filtered/reduced list a another and call another function called abc(). How can I do it using Java Streams?

pseudo:

big.getParts().stream.
//dividing logic logic
for(i < parts.size)
    abc(p)

Thanks

2
  • 2
    Your error comes because you have a list of BigRequest, yet you are calling Parts::getPartId on it, which is the same as calling BigRequest.getPartId() (not going to work). You will have to flatMap(bigParts -> bigParts.parts.stream()) and then it'll allow you to use Parts::getPartId. Commented Mar 30, 2017 at 13:12
  • 1
    However, it's usually not possible to create backpressure in stream by collecting Stream<T> into some kind of Stream<List<T>> - streams are by design operations on only single element at a time. You can unwrap Stream<List<T>> into a Stream<T>, but the opposite is not available for you. Commented Mar 30, 2017 at 13:14

1 Answer 1

1

You might use something like this:

 Map<String,List<Parts>> commonId = big.getParts().
                stream().
                collect(
                        Collectors.groupingBy(
                            Parts::getPartId,
                            Collectors.mapping(
                                Function.identity(),
                                Collectors.toList()
                            )
                        )
                ); 

and after it, you will just need to iterate over the map and apply your function. commonId.entrySet().stream().map(entry -> apply(entry))...

Updated We can omit Collectors.mapping(Function.identity(),Collectors.toList()) part, since it is a default behaviour of groupingBy

Map<String,List<Parts>> commonId = big.getParts().
                    stream().
                    collect(
                            Collectors.groupingBy(
                                Parts::getPartId
                            )
                    ); 
Sign up to request clarification or add additional context in comments.

9 Comments

Normal groupingBy collector is already mapping(identity(), toList()), is it not?
@M.Prokhorov, yes, you are totally right. We don't need - Collectors.mapping(Function.identity(),Collectors.toList()) part
@M. Prokhorov: well, groupingBy uses toList() by default and mapping(identity(), …) is even more redundant.
@Holger, to be honest, I was always using Collectors.mapping(Function.identity(),Collectors.toList()), I never new that toList() is default behaviour of groupingBy. What a shame! I will read java docs more carefully now.
But what is the purpose of wrapping a collector into a mapping(identity(), …) collector?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.