获取每周最大价值rom
Getting Weekly Max value rom
问题:
我有一个 Map<LocalDate, Integer>
,我想使用 LocalDate
按周对这些地图元素进行分组,并使用 [=69= 按周查找每个分组值的最大值] 8 流.
我目前遇到无法将密钥转换回流中的 LocalDate
对象的问题,因为我没有创建对象所需的数据字段LocalDate
进入地图。
如果我不将其转换为 LocalDate
并将其保留为 String
,我将无法使用 TreeMap
来排列键值使用按键的自然顺序。
如果我在分组数据时不将月份包括在 DateTimeFormatter.ofPattern
中,那么两年之间的周数可能会重叠。
如果我仅使用周数整数作为流中地图的输出,则按周分组的值将与另一年的周数混合并重叠,即 2020-2021 与第 1 周.
问题:
- 如何使用 java 流获取每周值的最大值?
数据集:
Map<LocalDate,Integer> CumulativeGarbageWasteDate = new HashMap<LocalDate,Integer>();
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2020"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("12/24/20"),DateTimeFormatter.ofPattern("M/d/yy")),140);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/20"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/1/21"),DateTimeFormatter.ofPattern("M/d/yy")),182);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/2/21"),DateTimeFormatter.ofPattern("M/d/yy")),203);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),321);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),421);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2021"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/6/21"),DateTimeFormatter.ofPattern("M/d/yy")),1200);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/31/21"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
代码:
private static Map<LocalDate, Integer> sumByWeek (Map<LocalDate,Integer> CumulativeGarbageWasteDate){
DateTimeFormatter formatter3 = new DateTimeFormatterBuilder().appendPattern("w/M/YY").parseDefaulting(ChronoField.DAY_OF_WEEK,DayOfWeek.FRIDAY.getValue()).toFormatter();
return CumulativeGarbageWasteDate
.entrySet()
.stream()
.collect(Collectors.groupingBy(
row-> LocalDate.parse(row.getKey().format(DateTimeFormatter.ofPattern("w/M/YY")),formatter3),
TreeMap::new,
Collectors.reducing(0, x->x.getValue(),Math::max)));
}
错误:
这里是我在运行代码时遇到的错误。
java.time.format.DateTimeParseException: Text '5/2/20' could not be parsed: Conflict found: Field MonthOfYear 1 differs from MonthOfYear 2 derived from 2020-01-31
输出映射将是 Map<LocalDate, Integer>
类型,其中键将是该周具有最高值的日期。 (我正在拆分解决方案以使其更易于理解)。
首先,我建议创建一个 class(可能是一个内部的 class)来保存日期及其对应的值。这将使处理变得容易。
private static class MyData {
private LocalDate date;
private int value;
// getters and a constructor
}
注意: 假设静态导入 Collectors
方法,如 grouping
、toMap
、toList
、mapping
在下面的代码中。
可以使用 WeekFields
.(Refer)
检索一年中的第几周
注意: row.getKey().getYear()
不应在下面的代码中代替 row.getKey().get(weekFields.weekBasedYear())
来获取年份,因为它可能会在场景中产生不正确的结果像:
2022-01-01
和 2021-12-31
,属于 2022 年的第 1 周。
所以如果我们使用getYear()
,那么各自生成的字符串
将是 1/2022
和 1/2021
,这是不正确的。
在这种情况下,预期的字符串将是 1/2022
.
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// function to generate a key of the form: week~year. year included to avoid overlap
Function<Entry<LocalDate, Integer>, String> groupFn
= row -> String.format("%d/%d",
row.getKey().get(weekFields.weekOfWeekBasedYear()),
row.getKey().get(weekFields.weekBasedYear()));
现在将输入转换为 MyData
个对象:
Map<String, List<MyData>> temp =
input.entrySet()
.stream()
.collect(groupingBy(groupFn,
TreeMap::new,
mapping(e -> new MyData(e.getKey(), e.getValue()), toList())));
现在我们找到一周内最大值的日期:
Function<Entry<String, List<MyData>>, MyData> maxDataFn
= entry -> entry.getValue()
.stream()
.collect(collectingAndThen(maxBy(Comparator.comparingInt(MyData::getValue)),
Optional::get));
TreeMap<LocalDate, Integer> result
= temp.entrySet()
.stream()
.map(maxDataFn)
.collect(toMap(MyData::getDate, MyData::getValue, Integer::max, TreeMap::new));
问题:
我有一个
Map<LocalDate, Integer>
,我想使用LocalDate
按周对这些地图元素进行分组,并使用 [=69= 按周查找每个分组值的最大值] 8 流.我目前遇到无法将密钥转换回流中的
LocalDate
对象的问题,因为我没有创建对象所需的数据字段LocalDate
进入地图。如果我不将其转换为
LocalDate
并将其保留为String
,我将无法使用TreeMap
来排列键值使用按键的自然顺序。如果我在分组数据时不将月份包括在
DateTimeFormatter.ofPattern
中,那么两年之间的周数可能会重叠。如果我仅使用周数整数作为流中地图的输出,则按周分组的值将与另一年的周数混合并重叠,即 2020-2021 与第 1 周.
问题:
- 如何使用 java 流获取每周值的最大值?
数据集:
Map<LocalDate,Integer> CumulativeGarbageWasteDate = new HashMap<LocalDate,Integer>();
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2020"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("12/24/20"),DateTimeFormatter.ofPattern("M/d/yy")),140);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/20"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/1/21"),DateTimeFormatter.ofPattern("M/d/yy")),182);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/2/21"),DateTimeFormatter.ofPattern("M/d/yy")),203);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),321);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/3/21"),DateTimeFormatter.ofPattern("M/d/yy")),421);
CumulativeGarbageWasteDate.put(LocalDate.parse(("5/2/2021"),DateTimeFormatter.ofPattern("[M/d/yyyy][M/d/yy]")),2400);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/6/21"),DateTimeFormatter.ofPattern("M/d/yy")),1200);
CumulativeGarbageWasteDate.put(LocalDate.parse(("01/31/21"),DateTimeFormatter.ofPattern("M/d/yy")),2400);
代码:
private static Map<LocalDate, Integer> sumByWeek (Map<LocalDate,Integer> CumulativeGarbageWasteDate){
DateTimeFormatter formatter3 = new DateTimeFormatterBuilder().appendPattern("w/M/YY").parseDefaulting(ChronoField.DAY_OF_WEEK,DayOfWeek.FRIDAY.getValue()).toFormatter();
return CumulativeGarbageWasteDate
.entrySet()
.stream()
.collect(Collectors.groupingBy(
row-> LocalDate.parse(row.getKey().format(DateTimeFormatter.ofPattern("w/M/YY")),formatter3),
TreeMap::new,
Collectors.reducing(0, x->x.getValue(),Math::max)));
}
错误:
这里是我在运行代码时遇到的错误。
java.time.format.DateTimeParseException: Text '5/2/20' could not be parsed: Conflict found: Field MonthOfYear 1 differs from MonthOfYear 2 derived from 2020-01-31
输出映射将是 Map<LocalDate, Integer>
类型,其中键将是该周具有最高值的日期。 (我正在拆分解决方案以使其更易于理解)。
首先,我建议创建一个 class(可能是一个内部的 class)来保存日期及其对应的值。这将使处理变得容易。
private static class MyData {
private LocalDate date;
private int value;
// getters and a constructor
}
注意: 假设静态导入 Collectors
方法,如 grouping
、toMap
、toList
、mapping
在下面的代码中。
可以使用 WeekFields
.(Refer)
注意: row.getKey().getYear()
不应在下面的代码中代替 row.getKey().get(weekFields.weekBasedYear())
来获取年份,因为它可能会在场景中产生不正确的结果像:
2022-01-01
和 2021-12-31
,属于 2022 年的第 1 周。
所以如果我们使用getYear()
,那么各自生成的字符串
将是 1/2022
和 1/2021
,这是不正确的。
在这种情况下,预期的字符串将是 1/2022
.
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// function to generate a key of the form: week~year. year included to avoid overlap
Function<Entry<LocalDate, Integer>, String> groupFn
= row -> String.format("%d/%d",
row.getKey().get(weekFields.weekOfWeekBasedYear()),
row.getKey().get(weekFields.weekBasedYear()));
现在将输入转换为 MyData
个对象:
Map<String, List<MyData>> temp =
input.entrySet()
.stream()
.collect(groupingBy(groupFn,
TreeMap::new,
mapping(e -> new MyData(e.getKey(), e.getValue()), toList())));
现在我们找到一周内最大值的日期:
Function<Entry<String, List<MyData>>, MyData> maxDataFn
= entry -> entry.getValue()
.stream()
.collect(collectingAndThen(maxBy(Comparator.comparingInt(MyData::getValue)),
Optional::get));
TreeMap<LocalDate, Integer> result
= temp.entrySet()
.stream()
.map(maxDataFn)
.collect(toMap(MyData::getDate, MyData::getValue, Integer::max, TreeMap::new));