使用基于键列表的流过滤器地图

时间:2019-06-14 16:44:34

标签: java collections java-8 java-stream

我有一个特殊的问题,想知道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的确切键时才能使用此方法,但是这样只会返回单个输入集。我对一张完全过滤的地图感兴趣,我正在努力实现这一目标。

3 个答案:

答案 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,"")));