我想将一个包含 per-day 销售额(无论什么,都无所谓)的列表转换为一个包含 per-month 销售额的列表。
所以我有一个List<Map<String, Object>>
perDay
,它包含这些每日值:
[{DATE=2022-01-01, COUNT=5}, {DATE=2022-01-02, COUNT=3}, {DATE=2022-02-29, COUNT=4}]
这些值应该被收集到每月的值中,如下所示:
[{DATE=2022-01, COUNT=8}, {DATE=2022-02, COUNT=4}]
我想使用groupingBy()
方法处理流。
下面是我的代码:
Map<String, Object> jan1 = new HashMap<>();
jan1.put("DATE", "2022-01-01"); jan1.put("COUNT", "5");
Map<String, Object> jan2 = new HashMap<>();
jan2.put("DATE", "2022-01-02"); jan2.put("COUNT", "3");
Map<String, Object> feb1 = new HashMap<>();
feb1.put("DATE", "2022-02-29"); feb1.put("COUNT", "4");
List<Map<String, Object>> perDay = List.of(jan1, jan2, feb1);
Map<String, Object> perMonth = perDay.stream()
.collect(Collectors.groupingBy("???",
Collectors.summingInt(f -> Integer.parseInt((String) f))));
我想,我快了,但还没到那一步。
有什么想法吗
3条答案
按热度按时间mbyulnm01#
假设你的约会总是有格式的
您可以尝试:
退货:
aiazj4mn2#
您所介绍的方法是不可维护的,因此容易出现错误和代码重复,并且也使代码的扩展更加困难。
这些是主要问题:
Object
作为泛型类型。因为Object
类型的集合元素如果没有强制转换就没有任何价值。如果你不想写充满强制转换和intanceof
检查的混乱代码,就不要这样做。Map
-不是与JSON对象相同的东西(* 我不是在谈论像Gson这样的Java库中的类,它们是基于Map的 ),不要混淆 * 构建人类可读文本的方式 * 与数据结构的实现*。"DATE"
和"COUNT"
这样的键是无用的-您可以简单地存储实际的日期和计数。String
作为数字和日期的类型不会给您带来任何好处。您无法对它们做任何事情(* 除了在控制台上比较和打印 *)没有解析,几乎就像Object
一样。为每个元素使用适当的数据类型。为什么?因为LocalDate
,Integer
,YearMonth
有自己独特的行为,这是String
无法提供的。这就是如何通过将表示 sales per day
List<Map<String, Object>>
的集合调优为更方便的Map<LocalDate, Integer>
来改进代码:这就是如何生成一个包含 sales per month 的Map(
java.time
包中的YearMonth
用作 key):A link to Online Demo
pbossiut3#
首先,我建议不要使用Map列表来进行日期销售或月份销售。
这是你的数据。
这就是你要做的。
但是你的初始
List<Map<String,Object>>
不允许你选择日期,因为Map的DATE值与列表的索引没有关系。但是,如果你将它们存储为Map<String,Integer>
,那么你就可以使用yyyy-MM-dd
的一致格式来检索任何DATE的计数。这个过程不需要强制转换。这也使得它更容易转换为月总销售额如下:
perDay
流式传输entrySets
Map<String,Integer>
。使用子字符串通过Entry.getKey()
仅获取年份和月份部分。注意:只有当你的日期格式是一致的时,这才有效。Entry::getValue
获取计数。印刷品
和以前一样,您可以获得任何
yyyy-MM
键的每月计数(如果存在)。建议:
Object
。使用一个特定的类型,在你的例子中,Integer作为值。否则你将不得不进行类型转换,这会导致错误。