我想将包含time
属性的对象列表分组为5分钟,最好使用流和收集器。
我在StackOverflow上找到的唯一可能的解决方案是计算我需要多少个间隔(子列表),将每个对象添加到这些列表中的每一个,并过滤掉那些不适合相应时间范围的对象,这不完全是很好的解决方案。
(你可以在这里找到主题:How to group elements of a List by elements of another in Java 8)
我想到了类似的东西:
List<MyObject> list = new ArrayList<MyObject>();
.......
List<List<MyObject>> grouped = list.stream().collect(Collectors.groupingBy(obj -> obj.getTime() / intervalLength));
这当然是最好的工作。
我希望,Java 8&amp;它的功能越来越多,我们可以为这样的问题找到一个suting解决方案。
此致 Claas M。
编辑: 在最后,我使用@Harsh Poddar的解决方案,并使用
将地图转换为列表列表for(Map.Entry<Integer, List<MyObject>> entry:map.entrySet())
list.add(entry.getValue());
注意:之后必须对List进行排序。
答案 0 :(得分:4)
这完全没问题:
Map<Long,<List<MyObject>> grouped = ticks.stream().collect(Collectors.groupingBy(obj -> obj.getTime() / intervalLength));
此方法将为您提供一个地图,您可以在该地图上调用.values()以获取列表列表。第一个元素将包含obj.getTime()从0到intervalLength的元素,只要有这样的元素。第二个将包含intervalLength到intervalLength * 2,依此类推
答案 1 :(得分:4)
使用函数将时间映射到存储桶:
// assume time is in seconds
int bucketNumber(int baseTime, int thisTime) {
return (thisTime - baseTime) / 300;
}
然后按桶号收集:
ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime()));
现在你有一个Map<Integer, List<Tick>>
,其中键是从baseTime
开始的五分钟桶的索引,以及该桶中的滴答列表。如果您只想要直方图,请使用下游收集器:
ticks.stream().collect(groupingBy(e -> bucketNumber(baseTime, e.getTime()),
counting());