我的列表格式如下:
int intervalInMinutes = 10;
String startTimeForGrouping = "2017-05-09T15:37:51.896+00:00";
List<MyObject> myObjList = Arrays.asList(
new MyObject("1","a","2017-05-09T15:38:51.896+00:00"),
new MyObject("1","a","2017-05-09T16:41:51.896+00:00"),
new MyObject("1","a","2017-05-09T16:49:51.896+00:00"),
new MyObject("1","a","2017-05-09T16:51:51.896+00:00"),
new MyObject("2","b","2017-05-09T17:38:51.896+00:00"),
new MyObject("2","b","2017-05-09T18:41:51.896+00:00")
);
我以上述格式获得了清单: 我想遍历整个过程,并按照给定的开始时间间隔进行一些分组,并实现如下: 在上面的列表中,组ID 1应该返回2个列表。
单个列表中的前2个对象,因为它位于从startTimeForGrouping开始的第一个间隔中(“ 2017-05-09T15:37:51.896 + 00:00” + intervalInMinutes(10))。
第3个和第4个列表在不同的列表中,因为它位于下一个间隔中(“ 2017-05-09T15:47:51.896 + 00:00” + intervalInMinutes(10))。 ID 2也应重复同样的逻辑
我已经尝试过了
Map<String, Map<Long, List<MyObject>>> aggrResult =
myObjList.stream()
.collect(
Collectors.groupingBy(
MyObject::getId,
Collectors.groupingBy(eachQueueObj -> eachQueueObj.getIntervalStartTime()/interval)));
但这是错误的,因为我想基于给定开始时间的间隔进行汇总。
由于Java流媒体是新手,请帮助我
答案 0 :(得分:3)
您应将日期字符串解析为Instant
对象,然后调用Duration.between
以获取持续时间。然后,将持续时间除以intervalInMinutes
分钟。最后,将此数字乘以intervalInMinutes
并将其添加到startTimeForGrouping
中以获得分组密钥。
在流操作之前,将startTimeForGrouping
解析为一个瞬间,然后从Duration
中创建一个startTimeForGrouping
:
Instant startInstant = OffsetDateTime.parse(startTimeForGrouping).toInstant();
Duration interval = Duration.ofMinutes(startTimeForGrouping);
然后您可以声明方法roundInstant
:
public static Instant roundInstant(Instant instant, Duration interval, Instant start) {
long multiple =
Duration.between(start, instant)
.getSeconds() / interval.getSeconds();
return start.plus(interval.multipliedBy(multiple));
}
第二个groupingBy
调用可以如下所示:
Collectors.groupingBy(
eachQueueObj -> roundInstant(
OffsetDateTime.parse(eachQueueObj.getIntervalStartTime()).toInstant(),
interval,
startInstant
).getEpochSecond()
)
事实上,我建议您不要使用String
和Long
,而直接使用Instant
。
答案 1 :(得分:1)
我认为代码是,您可以尝试重新修改getTime方法以解决您的需求
package com.test;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
*
*
*
*
*
* @author shikai.liu
* @version 1.0
* @since JDK1.7
*/
public class TestList {
public static String strDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
public static SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
public static class MyObject {
public String id;
public String code;
public String time;
public MyObject(String id, String code, String time) {
this.code = code;
this.id = id;
this.time = time;
}
public String getId() {
return this.id;
}
public String getIntervalStartTime() {
return time;
}
public long getTime(Integer t, String srcTime) {
long result = 0;
try {
Date dstDate = sdf.parse(time);
Date srcDate = sdf.parse(srcTime);
long inteval = dstDate.getTime() - srcDate.getTime();
result = inteval / (1000 * 60) / t;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
public static void main(String[] args) throws Exception {
int intervalInMinutes = 10;
String startTimeForGrouping = "2017-05-09T15:37:51.896+00:00";
List<MyObject> myObjList = Arrays.asList(new MyObject("1", "a", "2017-05-09T15:38:51.896+00:00"), new MyObject("1", "a",
"2017-05-09T16:41:51.896+00:00"), new MyObject("1", "a", "2017-05-09T16:49:51.896+00:00"), new MyObject("1", "a",
"2017-05-09T16:51:51.896+00:00"), new MyObject("2", "b", "2017-05-09T17:38:51.896+00:00"), new MyObject("2", "b",
"2017-05-09T18:41:51.896+00:00"));
Map<String, Map<Long, List<MyObject>>> aggrResult = myObjList.stream().collect(
Collectors.groupingBy(MyObject::getId, Collectors.groupingBy(a -> a.getTime(intervalInMinutes, startTimeForGrouping))));
System.out.println(1);
}
}