Java - Collectors.groupingBy - 最近 15 天
Java - Collectors.groupingBy - the last 15 days
是否可以使用 Java 的 Collectors.groupingBy
按过去 15 天分组?
输入:
public class Tweet {
String id;
LocalDate createdAt;
// Constructor Ignored
List<Tweet> tweets = new ArrayList(){{
add(new Tweet("1", "2021-11-17"));
add(new Tweet("2", "2021-11-16"));
add(new Tweet("3", "2021-11-14"));
add(new Tweet("4", "2021-11-13"));
add(new Tweet("5", "2021-11-12"));
add(new Tweet("7", "2021-10-09"));
add(new Tweet("8", "2021-10-08"));
add(new Tweet("9", "2021-10-07"));
add(new Tweet("10", "2021-09-02"));
add(new Tweet("11", "2021-09-01"));
...
}};
}
预期输出:
2021-11-17: (group must include 2021-11-17 + 15 days before 17th)
Tweet("1", "2021-11-17");
Tweet("2", "2021-11-16");
Tweet("3", "2021-11-14");
Tweet("4", "2021-11-13");
Tweet("5", "2021-11-12");
2021-10-09: (group to include 2021-10-09 + 15 days before 9th)
Tweet("7", "2021-10-09");
Tweet("8", "2021-10-08");
Tweet("9", "2021-10-07");
2021-09-01: (group to include 2021-09-01 + 15 days before 1st)
Tweet("10", "2021-09-02");
Tweet("11", "2021-09-01");
当前逻辑(不工作):
主要方法:
TemporalAdjusters adjuster = TemporalAdjusters.ofDateAdjuster(d -> d.minusDays(15));
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item -> item.createdAt())
.with(adjuster)));
System.out.println(groupByLast15Days); // provides incorrect results
非常感谢任何帮助!谢谢!
您可以使用 ChronoUnit.DAYS.between(from,to)
获得两个 LocalDateTime
之间的日期差异,如 here 所述。
然后您可以将其除以 15(因此该范围内的所有天数都相同):
LocalDate origin=LocalDate.now();
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item->
Long.valueOf(ChronoUnit.DAYS.between(item.createdAt(),origin)/15));
如果要按开始日期分组,可以逆向计算(而15天之间的差异被整数除法消除):
LocalDate origin=LocalDate.now();
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item ->
origin.plusDays(
(ChronoUnit.DAYS.between(origin, item.createdAt()) /15)*15
)
));
如果你想使用TemporalAdjusters
,你可以这样做:
LocalDate origin=LocalDate.now();
TemporalAdjusters adjuster = TemporalAdjusters.ofDateAdjuster(d ->
origin.plusDays(
(ChronoUnit.DAYS.between(origin, d) /15)*15
)
);
解释:
一个整数除以另一个整数总是得到一个整数,即使商有小数位。整数除法只是删除那些小数位。如果您将一个数字除以 15,它将 return 15 个连续数字的结果相同。再次乘以 15 后,您将得到这 15 个数字中的第一个。将一个数字除以 15 再乘以 15 的目的是每 15 个连续的数字设置为相同的数字(这 15 个中的第一个)。
ChronoUnit.DAYS.between(date1, date2)
只是计算date1
和date2
之间的天数。
是否可以使用 Java 的 Collectors.groupingBy
按过去 15 天分组?
输入:
public class Tweet {
String id;
LocalDate createdAt;
// Constructor Ignored
List<Tweet> tweets = new ArrayList(){{
add(new Tweet("1", "2021-11-17"));
add(new Tweet("2", "2021-11-16"));
add(new Tweet("3", "2021-11-14"));
add(new Tweet("4", "2021-11-13"));
add(new Tweet("5", "2021-11-12"));
add(new Tweet("7", "2021-10-09"));
add(new Tweet("8", "2021-10-08"));
add(new Tweet("9", "2021-10-07"));
add(new Tweet("10", "2021-09-02"));
add(new Tweet("11", "2021-09-01"));
...
}};
}
预期输出:
2021-11-17: (group must include 2021-11-17 + 15 days before 17th)
Tweet("1", "2021-11-17");
Tweet("2", "2021-11-16");
Tweet("3", "2021-11-14");
Tweet("4", "2021-11-13");
Tweet("5", "2021-11-12");
2021-10-09: (group to include 2021-10-09 + 15 days before 9th)
Tweet("7", "2021-10-09");
Tweet("8", "2021-10-08");
Tweet("9", "2021-10-07");
2021-09-01: (group to include 2021-09-01 + 15 days before 1st)
Tweet("10", "2021-09-02");
Tweet("11", "2021-09-01");
当前逻辑(不工作):
主要方法:
TemporalAdjusters adjuster = TemporalAdjusters.ofDateAdjuster(d -> d.minusDays(15));
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item -> item.createdAt())
.with(adjuster)));
System.out.println(groupByLast15Days); // provides incorrect results
非常感谢任何帮助!谢谢!
您可以使用 ChronoUnit.DAYS.between(from,to)
获得两个 LocalDateTime
之间的日期差异,如 here 所述。
然后您可以将其除以 15(因此该范围内的所有天数都相同):
LocalDate origin=LocalDate.now();
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item->
Long.valueOf(ChronoUnit.DAYS.between(item.createdAt(),origin)/15));
如果要按开始日期分组,可以逆向计算(而15天之间的差异被整数除法消除):
LocalDate origin=LocalDate.now();
Map<LocalDate, List<Tweets>> groupByLast15Days = tweets.stream()
.collect(Collectors.groupingBy(item ->
origin.plusDays(
(ChronoUnit.DAYS.between(origin, item.createdAt()) /15)*15
)
));
如果你想使用TemporalAdjusters
,你可以这样做:
LocalDate origin=LocalDate.now();
TemporalAdjusters adjuster = TemporalAdjusters.ofDateAdjuster(d ->
origin.plusDays(
(ChronoUnit.DAYS.between(origin, d) /15)*15
)
);
解释:
一个整数除以另一个整数总是得到一个整数,即使商有小数位。整数除法只是删除那些小数位。如果您将一个数字除以 15,它将 return 15 个连续数字的结果相同。再次乘以 15 后,您将得到这 15 个数字中的第一个。将一个数字除以 15 再乘以 15 的目的是每 15 个连续的数字设置为相同的数字(这 15 个中的第一个)。
ChronoUnit.DAYS.between(date1, date2)
只是计算date1
和date2
之间的天数。