Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Group Objects in a List into other Lists by Attribute using streams & Java 8?

I want to group a List of Objects containing a time attribute into 5-Minute intervals, preferably using streams and collectors.

The only possible solution I found on StackOverflow is to calculate how many intervals (sublists) I need, add every object to every one of these Lists and filter out the ones that dont fit into the respective timeframe, which is not exactly a nice solution.

(You can find the Thread here: How to group elements of a List by elements of another in Java 8)

I thought of something similar to this:

List<MyObject> list = new ArrayList<MyObject>();
.......
List<List<MyObject>> grouped = list.stream().collect(Collectors.groupingBy(obj -> obj.getTime() / intervalLength));

This of course doenst work.

I hope that, with Java 8 & its features being used more and more, we can find a suting solution for such a Problem.

Regards, Claas M.

EDIT: In the End, I used @Harsh Poddar's solution and converted the Map into a List of Lists using

for(Map.Entry<Integer, List<MyObject>> entry:map.entrySet())
  list.add(entry.getValue());

Note: The List had to be sorted afterwards.

like image 758
Claas M. Avatar asked May 23 '15 17:05

Claas M.


People also ask

How to GROUP BY data in Java?

The groupingBy() method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance. In order to use it, we always need to specify a property by which the grouping would be performed. This method provides similar functionality to SQL's GROUP BY clause.

Can we convert stream to list in Java?

Using Collectors. Get the Stream to be converted. Collect the stream as List using collect() and Collectors. toList() methods. Convert this List into an ArrayList.


1 Answers

This works totally fine:

Map<Long,<List<MyObject>> grouped = ticks.stream().collect(Collectors.groupingBy(obj -> obj.getTime() / intervalLength));

This method will give you a map on which you may then call .values() to get the list of lists. First element will contain elements with obj.getTime() from 0 to intervalLength provided there were such elements. The second will contain from intervalLength to intervalLength*2 and so on

like image 180
Harsh Poddar Avatar answered Sep 25 '22 15:09

Harsh Poddar