我能理解这一点吗?这是Java开发人员如何做到的?或者有更好的方法吗?
因此,如果我想在地图中找到与谓词匹配的键,我必须首先通过方便提供的方法从地图中获取键集。那么,我必须通过方便提供的方法将集合转换为流。那么,我必须通过方便提供的方法用我的谓词过滤流。然后,我必须通过方便提供的方法将流转换为我选择的类型的容器,可能提供收集器。那么,我至少可以检查容器是否为空,以便知道是否有任何匹配。只有这样我才能使用密钥来提取感兴趣的值,或者我可以从头开始使用条目集,并为自己节省额外的步骤。
这是真的吗?因为据我所知,没有其他方法可以内置到地图中,也可以作为通用搜索算法提供给迭代器或其他容器抽象。
答案 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之间有明显的分离。