如何在Java中搜索与谓词匹配的键的映射?

时间:2016-09-15 18:23:29

标签: java java-8

我能理解这一点吗?这是Java开发人员如何做到的?或者有更好的方法吗?

因此,如果我想在地图中找到与谓词匹配的键,我必须首先通过方便提供的方法从地图中获取键集。那么,我必须通过方便提供的方法将集合转换为流。那么,我必须通过方便提供的方法用我的谓词过滤流。然后,我必须通过方便提供的方法将流转换为我选择的类型的容器,可能提供收集器。那么,我至少可以检查容器是否为空,以便知道是否有任何匹配。只有这样我才能使用密钥来提取感兴趣的值,或者我可以从头开始使用条目集,并为自己节省额外的步骤。

这是真的吗?因为据我所知,没有其他方法可以内置到地图中,也可以作为通用搜索算法提供给迭代器或其他容器抽象。

3 个答案:

答案 0 :(得分:6)

我自己也更喜欢entrySet。你应该发现这个有效:

Map<String, Integer> map; //Some example Map
//The map is filled here

List<Integer> valuesOfInterest = map.entrySet()
                                 .stream() //Or parallelStream for big maps
                                 .filter(e -> e.getKey().startsWIth("word")) //Or some predicate
                                 .map(Map.Entry::getValue) //Get the values
                                 .collect(Collectors.toList()); //Put them in a list

如果没有匹配,则列表为空。如果多个键与谓词匹配,这将非常有用。

答案 1 :(得分:2)

简而言之,它就像:

Predicate<T> predicate = (t -> <your predicate here>);
return myMap.keySet()
    .stream()
    .filter(predicate)
    .findAny()
    .map(myMap::get);
如果没有键匹配,

返回null

(nota:findAny优于findFirst,因为它不会阻止并行化(如果相关),findFirst无论如何都是无用的,因为Set键没有排序任何有意义的方式)

答案 2 :(得分:1)

目前尚不清楚你为何经常喊“那么”。它是解决问题的标准方法,结合为各种用例设计的工具,以获得特定的结果。有一个内置的功能可以遍历一系列元素并搜索匹配,即Stream API。此外,Map界面为您提供了集合视图,keySet()entrySet()values(),以便能够使用对集合进行操作的任意工具,流API就是其中之一。

因此,如果您有Map<Key,Value>并且对其键与谓词匹配的值感兴趣,则可以使用

List<Value> valuesOfInterest = map.entrySet().stream()
    .filter(e -> e.getKey().fulfillsCondition())
    .map(Map.Entry::getValue)
    .collect(Collectors.toList());

包含三个主要步骤,filter用于选择匹配,map用于指定您是否对每个匹配的键,值,条目或转换值感兴趣,collect(Collectors.toList())指定您要将结果收集到List

这些步骤中的每一个都可以由不同的选择替换,并且整个流管道可以通过额外的处理步骤来增强。由于您需要这种特定的操作组合,因此必须准确指定这三个步骤而不是为您的特定用例获取便捷方法。

需要entrySet().stream()的初始步骤,因为您必须选择条目集作为起点并切换到Stream API,它是用于不修改源的元素处理的专用API。另一方面,Collection API为您提供了可能会改变源的方法。如果您愿意使用它,则替代上述代码

map.keySet().removeIf(key -> !key.fulfillsCondition());
Collection<Value> valuesOfInterest=map.values();

的不同之处在于确实从源地图中删除了不匹配的条目。当然,你不想混淆这两者,所以它应该是可以理解的,为什么Collection API和Stream API之间有明显的分离。