使用Java 8按时间间隔对LocalDateTime对象进行分组

时间:2020-08-20 15:03:33

标签: java java-8 java-time

我有以下格式的列表,并且希望将此列表按分钟间隔进行分组。

 List<Item> myObjList = Arrays.asList(
                new Item(LocalDateTime.parse("2020-09-22T00:13:36")), 
                new Item(LocalDateTime.parse("2020-09-22T00:17:20")),
                new Item(LocalDateTime.parse("2020-09-22T01:25:20")),
                new Item(LocalDateTime.parse("2020-09-18T00:17:20")),
                new Item(LocalDateTime.parse("2020-09-19T00:17:20")));

例如,给定间隔10分钟,列表的前2个对象应该在同一组中,第3个对象应该在不同的组中,依此类推。

是否可以使用Java的8 groupingBy函数将此列表分组为间隔?

我的解决方案是将列表中的每个日期与列表中的所有其他日期进行比较,并在新列表中添加相差X分钟的日期。这似乎很慢且“棘手”,但我想知道是否有更稳定的解决方案。

2 个答案:

答案 0 :(得分:6)

可以使用Collectors#groupingByLocalDateTime对象分组为10分钟间隔的列表。您必须修改此代码段才能与Item类一起使用,但是逻辑是相同的。

List<LocalDateTime> myObjList = Arrays.asList(
    LocalDateTime.parse("2020-09-22T00:13:36"),
    LocalDateTime.parse("2020-09-22T00:17:20"),
    LocalDateTime.parse("2020-09-22T01:25:20"),
    LocalDateTime.parse("2020-09-18T00:17:20"),
    LocalDateTime.parse("2020-09-19T00:17:20")
);

System.out.println(myObjList.stream().collect(Collectors.groupingBy(time -> {
    // Store the minute-of-hour field.
    int minutes = time.getMinute();

    // Determine how many minutes we are above the nearest 10-minute interval.
    int minutesOver = minutes % 10;

    // Truncate the time to the minute field (zeroing out seconds and nanoseconds),
    // and force the number of minutes to be at a 10-minute interval.
    return time.truncatedTo(ChronoUnit.MINUTES).withMinute(minutes - minutesOver);
})));

输出

{
    2020-09-22T00:10=[2020-09-22T00:13:36, 2020-09-22T00:17:20],
    2020-09-19T00:10=[2020-09-19T00:17:20],
    2020-09-18T00:10=[2020-09-18T00:17:20],
    2020-09-22T01:20=[2020-09-22T01:25:20]
}

答案 1 :(得分:2)

您没有为组指定密钥,所以我只使用(minutes/10)*10的商来将标记为分钟的时间范围的开始数分钟截断为小时。

List<Item> myObjList = Arrays.asList(
        new Item(LocalDateTime.parse("2020-09-22T00:13:36")),
        new Item(LocalDateTime.parse("2020-09-22T00:17:20")),
        new Item(LocalDateTime.parse("2020-09-22T01:25:20")),
        new Item(LocalDateTime.parse("2020-09-18T00:17:20")),
        new Item(LocalDateTime.parse("2020-09-19T00:17:20")));

Map<String, List<Item>> map = myObjList.stream()
        .collect(Collectors.groupingBy(item -> {
            int range =
                    (item.getTime().getMinute() / 10) * 10;
            return item.getTime()
                    .truncatedTo(ChronoUnit.HOURS).plusMinutes(range) +
                    " - " + (range + 9) + ":59";
        }));

        
map.entrySet().forEach(System.out::println);

打印

2020-09-22T00:10 - 19:59=[2020-09-22T00:13:36, 2020-09-22T00:17:20]
2020-09-19T00:10 - 19:59=[2020-09-19T00:17:20]
2020-09-18T00:10 - 19:59=[2020-09-18T00:17:20]
2020-09-22T01:20 - 29:59=[2020-09-22T01:25:20]

这是我使用的课程。

class Item {
    LocalDateTime ldt;
    
    public Item(LocalDateTime ldt) {
        this.ldt = ldt;
    }
    
    public String toString() {
        return ldt.toString();
    }
    
    public LocalDateTime getTime() {
        return ldt;
    }
}