[英]Convert values in a List of Maps with Streaming API
I have a list of maps with non distinctive keys and like to modify each map value with Streaming API . 我有一个具有非唯一键的地图列表,并且喜欢使用Streaming API修改每个地图值。 The result should be a new list, the original one has to remain unchanged.
结果应该是一个新列表,原始列表必须保持不变。
Example data: 示例数据:
// [ {jpg=firstImage.jpg, png=firstImage.png}, {jpg=secondImage.jpg, png=secondImage.png} ]
Map<String, String> map1 = new HashMap<>();
map1.put("jpg", "firstImage.jpg");
map1.put("png", "firstImage.png");
Map<String, String> map2 = new HashMap<>();
map2.put("jpg", "secondImage.jpg");
map2.put("png", "secondImage.png");
List<Map<String, String>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
Let's assume I want to convert the filename to upper case. 假设我想将文件名转换为大写。 With distinctive values I could do the following:
利用独特的价值观,我可以做到以下几点:
Map<String, String> copy = list.stream()
.flatMap(e -> e.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toUpperCase()));
But flatMap does not work when keys aren't distinctive, and it would destroy my List<Map<String, String>>
structure. 但是,当键不具有唯一性时, flatMap不起作用,它将破坏我的
List<Map<String, String>>
结构。 I know that the structure is bad, but I can't change it. 我知道结构不好,但是我无法更改。
Expected outcome: 预期结果:
// [ {jpg=FIRSTIMAGE.JPG, png=FIRSTIMAGE.PNG}, {jpg=SECONDIMAGE.JPG, png=SECONDIMAGE.PNG} ]
I'd like to achieve this with Streaming API and avoid nested loops if possible. 我想通过Streaming API实现此目标,并尽可能避免嵌套循环。
You can't use flatMap
, because this way you would concat all Entries in a single Stream and thus loose the possibility to get them back. 您不能使用
flatMap
,因为这样您将在单个Stream中合并所有Entries,从而失去了将它们取回的可能性。
You need to convert each individual element from your List
, like this for example: 您需要转换
List
每个元素,例如:
List<Map<String, String>> result = list.stream()
.map(map -> map.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> e.getValue().toUpperCase())))
.collect(Collectors.toList());
System.out.println(result);
// [{jpg=FIRSTIMAGE.JPG, png=FIRSTIMAGE.PNG}, {jpg=SECONDIMAGE.JPG, png=SECONDIMAGE.PNG}]
Here's an option 这是一个选择
list.forEach(map -> map.replaceAll((t, f) -> f.toUpperCase()));
I am modifying the existing maps in your list. 我正在修改您列表中的现有地图。 And it's not using streams.
而且它不使用流。
Edit: Thanks to VGR for the great simplification. 编辑:感谢VGR的极大简化。
Edit: Since you need to leave your original structure unmodified, Eugene's solution is fine. 编辑:由于您需要保持原始结构不变,因此Eugene的解决方案很好。 You may also apply
replaceAll()
on a copy. 您也可以在副本上应用
replaceAll()
。 One example: 一个例子:
List<Map<String, String>> result = new ArrayList<>(list);
list.replaceAll(m -> {
Map<String, String> newMap = new HashMap<>(m);
newMap.replaceAll((t, f) -> f.toUpperCase());
return newMap;
});
Or yet a different approach, this one with a stream: 还是另一种方法,该方法带有流:
List<Map<String, String>> result = list.stream()
.map(m -> {
Map<String, String> newMap = new HashMap<>(m);
newMap.replaceAll((t, f) -> f.toUpperCase());
return newMap;
})
.collect(Collectors.toList());
Which to prefer, I'd say it's mostly a matter of taste. 我想说哪个更喜欢味道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.