请考虑以下示例代码:
Function<Pair<String, String>, Integer> lengthOfKey
= p -> p.getKey().length();
Collector<Pair<String, String>, ?, Map<String, String>>
convertPairListToMap =
Collectors.toMap(
Pair<String, String>::getKey,
Pair<String, String>::getValue);
Function<Map<String, String>, Map<String, String>>
convertValueToUpperCase =
map -> map.entrySet().stream().collect(
Collectors.toMap(
Map.Entry::getValue,
e -> e.getValue().toUpperCase())
);
list.stream()
.collect(groupingBy(
lengthOfKey,
collectingAndThen(
convertPairListToMap,
convertValueToUpperCase
)))
.forEach((keyLength, map) -> {
// ...
});
我喜欢写作
collectingAndThen(
convertPairListToMap,
convertValueToUpperCase
明确指出Pairs列表被转换为Map并且Values被修改。我不想在收集器内部进行大写转换,将列表转换为映射,因为这样收集器所做的不仅仅是将对列表转换为收集器名称所示的映射。但是,我不喜欢在这个解决方案中,流被收集两次 - 这效率低下,不是吗?因此,我想知道是否有一种解决方案仅收集一次流,但仍然明确说明到 Map 的转换和值的转换。我在 API 中搜索了组合两个
Collectors.toMap
调用的方法,但找不到任何内容。
如果您可以通过共享实现来简化和共享您试图解决的问题,那么您很可能会得到更好、更简单的解决方案。
看起来,以下内容应该可以满足您的要求(除了
merging
)
Map<Integer, Map<String, String>> groupingAndTransformation = list.stream()
.collect(Collectors.groupingBy(
p -> p.getKey().length(),
Collectors.toMap(Pair<String, String>::getValue,
e -> e.getValue().toUpperCase())));