我有一个特殊的问题,想知道Java 8 Streams API是否可以解决它。我知道可以在使用Streams API之外完成此操作,但如果可以使用Streams完成此操作,则我不想添加与尝试实现该代码相关的所有样板代码。我有一张地图
Map<String, String> greetings = new HashMap<>();
greetings.put("abc", "Hello");
greetings.put("def", "Goodbye");
greetings.put("ghi", "Ciao");
greetings.put("xyz", "Bonsoir");
和键列表:
List<String> keys = Arrays.asList("def", "zxy");
并将以上内容与Streams API结合使用,可以将其过滤为:
Map<String, String> filteredGreetings = new HashMap<>();
filteredGreetings.put("def", "Goodbye");
filteredGreetings.put("xyz", "Bonsoir");
希望这是我想要实现的目标。
到目前为止,我只有在指定用于过滤地图的keySet的确切键时才能使用此方法,但是这样只会返回单个输入集。我对一张完全过滤的地图感兴趣,我正在努力实现这一目标。
答案 0 :(得分:4)
如果问题is not a typo中的输入和预期输出,您还可以将输入映射的键保留为:
Map<String, String> futureGreetings = new HashMap<>(greetings);
futureGreetings.keySet().retainAll(keys);
答案 1 :(得分:3)
尝试一下:
Map<String, String> result = keys.stream()
.filter(greetings::containsKey)
.collect(Collectors.toMap(Function.identity(), greetings::get));
反之亦然:
Map<String, String> result = greetings.entrySet().stream()
.filter(e -> keys.contains(e.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
对于第二种方法,我建议将Set<String>
用于更大的keys
列表,因为它对于.contains()
具有 O(1)时间复杂度因为它不包含任何重复项:
Set<String> keys = new HashSet<>(Arrays.asList("def", "zxy"));
答案 2 :(得分:0)
尝试
filteredGreetings= keys.stream()
.collect(Collectors.toMap(Function.identity(),key->greetings.get(key)));
,或者即使没有密钥,也可以使用getOrDefault()
方法。
... .collect(Collectors.toMap(Function.identity(),key->greetings.getOrDefault(key,"")));