我需要通过将List
Input Map< String,List< String>> - {"Fruit" -> ["apple","orange"], "Animal" -> ["cat","dog"]}
Input List< String> - {"apple","dog","xyzzy"}
output map as {"Fruit" -> "apple","Animal" -> "dog"} by discarding unmatching entries like "xyzzy" in this case"
```
Map <String, String> outputMap = new HashMap<>();
Map <String, String> tempMap = new HashMap<>();
for (Map.Entry<String, List<String>> entry : inputMap.entrySet()) {
entry.getValue().forEach(value -> tempMap.put(value, entry.getKey()));
}
inputList.forEach(value ->
{
if(tempMap.get(value)!=null)
outputMap.put(tempMap.get(value),value); });
}
如果由于重复,列表包含多个值属于同一键,则上述代码将失败。例如
输入图
Input List< String> - {"apple","dog","cat"}
将地图输出为{"Fruit" -> "apple","Animal" -> "cat"} ("dog" is overriden by "cat")
有没有一种方法可以获取输出
{"Fruit" -> "apple","Animal" -> "dog", "Animal" -> "cat"}
有没有办法以更整洁和精确的方式实现这一目标?
答案 0 :(得分:0)
由于您的输出类型为Map<String, List<String>>
,因此无法获取输出
{"Fruit" -> "apple","Animal" -> "dog", "Animal" -> "cat"}
({String
“动物” 为key
,不能重复)
但是,如果要过滤输入地图以检查包含列表,可以执行以下操作:
final Map<String, List<String>> inputMap = new HashMap<>();
inputMap.put("Fruit", asList("apple", "orange"));
inputMap.put("Animal", asList("cat", "dog"));
final List<String> list = asList("apple", "dog", "cat");
final Map<String, List<String>> outputMap = inputMap.entrySet().stream()
.filter(e -> e.getValue().stream().anyMatch(list::contains))
.collect(toMap(e -> e.getKey(), e -> e.getValue().stream().filter(list::contains).collect(toList())));
outputMap.forEach((k, v) -> System.out.printf("%s: %s%n", k, v));
输出:
Fruit: [apple]
Animal: [cat, dog]
两次过滤遍历两次,根据输入映射的方式,这将是好是坏。无论如何,不需要重新分组;如果输入匹配比例很高,则可以执行以下操作:
final Map<String, List<String>> outputMap = inputMap.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), e.getValue().stream().filter(list::contains).collect(toList())))
.filter(e -> !e.getValue().isEmpty())
.collect(toMap(e -> e.getKey(), e -> e.getValue()));
一个不直接相关的问题是,为了提高性能,最好将过滤器列表定义为Set<String>
。