如何合并两个地图<字符串,本地日期时间>并以纳秒为单位计算值之间的差异



everyone. 我在尝试合并两张地图时遇到了这个问题Map<String, LocalDateTime>.IDE 显示编译错误:

不能从静态上下文引用非静态方法

问题是我需要将它们合并到一个具有不同参数作为值的新地图中,在这种情况下,我需要计算第一个地图的LocalDateTime与第二个地图的 LocalDateTime 之间的差异,因此结果应该Map<String, Long>

Map<String, Long> result = Stream.concat(logStartTimeMap.entrySet().stream(), logEndTimeMap.entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(value1, value2) -> new Long(ChronoUnit.NANOS.between(value1,value2))));

我在Map.Entry::getKey,Map.Entry::getValue行中出现错误。

另一个ChronoUnit.NANOS.between(value1,value2)IDE 认为值 1 和值 2 是对象类型而不是临时类型。这很奇怪,因为以前我在生成的 Map 中选择不正确的参数类型时遇到了错误。但在这里没关系,ChronoUnit.NANOS.between(value1,value2)返回 Long 和 Map 结果将 Long 作为参数。

您使用Collectors.toMap的方式意味着您正在尝试返回Map<String, LocalDateTime>。这是因为Map.Entry::getKey返回一个StringMap.Entry::getValue返回一个LocalDateTime。然后在合并函数中,您尝试返回与泛型签名不匹配的Long

相反,您可以执行以下操作:

Map<String, LocalDateTime> map1 = ...;
Map<String, LocalDateTime> map2 = ...;
Map<String, Duration> result = map1.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
entry -> Duration.between(entry.getValue(), map2.get(entry.getKey()))
));

上面计算了一个Duration,它为您提供了比纳秒更大的灵活性,但您显然可以更改它以满足您的需求:

Map<String, LocalDateTime> map1 = ...;
Map<String, LocalDateTime> map2 = ...;
Map<String, Long> result = map1.entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().until(map2.get(entry.getKey()), ChronoUnit.NANOS)
));

请注意上面的两个示例都假定map1的键集是map2的键集的子集。在评论中,您说:

我在两张地图中都有相同的键。数学键必须位于第二个映射中。因此消除了没有匹配键的情况

这意味着该假设是有效的。但是,如果该假设不正确,您需要做的就是添加一个过滤器操作,在该操作中排除map2中不存在键的map1的任何条目。拉文德拉在他的回答中展示了一个例子。

我认为无法通过将两个地图合并到一个流中来做到这一点。

合并函数(Collectors.toMap的第三个参数(必须是BinaryOperator<U>。这意味着类似于(U,U(->U。但是在您的代码中,它采用两个类型LocalDateTime的参数并返回一个Long

您可以使用这样的流来做到这一点:

Map<String, Long> result = logStartTimeMap.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), ChronoUnit.NANOS.between(e.getValue(), logEndTimeMap.get(e.getKey()))))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

最新更新