Reputation: 267
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.
Upvotes: 5
Views: 6569
Reputation: 2554
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
Upvotes: 5
Reputation: 95356
Use a function to map a time to a bucket:
// assume time is in seconds
int bucketNumber(int baseTime, int thisTime) {
return (thisTime - baseTime) / 300;
}
Then collect by bucket number:
ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime()));
Now you have a Map<Integer, List<Tick>>
where the key is the index of the five-minute bucket starting at baseTime
, and a list of ticks in that bucket. If you just want a histogram, use a downstream collector:
ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime()),
counting());
Upvotes: 4