如何基于一组条目过滤地图条目

9
我正在使用Google Guava 12,并拥有一个地图:
Map<OccupancyType, BigDecimal> roomPrice;

我有一个集合:

Set<OccupancyType> policy;

我该如何基于 policy 过滤 roomPrice map 中的条目并返回过滤后的映射表? filteredMap 需要包含来自 policy 的所有值。如果在 roomPrice map 中没有来自 policy 的条目,我希望输入默认值。请保留所有html标签。

这个回答解决了你的问题吗?基于键列表获取子HashMap的最佳方法是什么? - tkruse
3个回答

29

由于你有一组键,你应该使用Maps.filterKeys(),此外Guava提供了一组相当不错的预定义谓词可供使用。 在你的情况下,像Predicates.in()这样的东西应该工作。

所以基本上你会得到:

Map<OccupancyType, BigDecimal> filteredMap
    = Maps.filterKeys(roomPrice, Predicates.in(policy));
希望能帮到你。

谢谢!我对Predicates还非常陌生,不确定它如何生成适用于我的地图的谓词。另外,有没有办法确保filteredMap应该具有来自policy的所有值。如果roomPrice映射没有来自policy的条目,则我想输入默认值。 - brainydexter
如果你有一个带有“default”条目的映射,你可以这样做:filteredMap.putAll(Maps.difference(filteredMap, defaultMap).entriesOnlyOnRight()); - Francisco Paulo
1
另外,您可以查看这篇文章:http://scaramoche.blogspot.de/2010/08/googles-guava-library-tutorial-part-4.html 它有一些 Predicate 使用的好例子。 - Francisco Paulo
1
Maps.filterKeys()通常不是一个好的解决方案,因为它会产生原始Map的liveView,并且对于像contains()或size()这样的方法,其复杂度为O(n)。最好使用https://dev59.com/lF4b5IYBdhLWcg3wojFg中提供的答案。 - tkruse

2
  • OccupancyType中覆盖并实现equalshashcode
  • 循环遍历roomPrice的键集,并收集过滤器中包含的元素。

类似这样:

Map<OccupancyType, BigDecimal> filteredPrices = new HashMap<OccupancyType, BigDecimal>();
for(OccupancyType key : roomPrice.keySet()) {
    if(policy.contains(key) {
        filteredPrices.put(key, roomPrice.get(key));
    }
}

更新:
好的,经过对Google Guava的了解,您应该能够做到类似以下操作:
Predicate<OccupancyType> priceFilter = new Predicate<OccupancyType>() {
    public boolean apply(OccupancyType i) {
        return policy.contains(i);
    }
};

然后

return Maps.filterValues(roomPrice, priceFlter);

应该能解决问题。

谢谢!我知道那个方法能用,但是我也在学习使用Guava库。我希望能够使用类似Maps.filterEntries(...) [link](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Maps.html#filterEntries(java.util.Map, com.google.common.base.Predicate)) [/link] 的东西来过滤Map。你有没有想法如何使用这个呢? - brainydexter
好的,我在阅读了一些资料后更新了我的答案,请告诉我它是否有效! - Jeshurun
你不觉得应该是 Maps.filterEntries(roomPrice, priceFilter); 吗? - brainydexter

0

不需要使用Guava,同时Maps.filterKeys()对于大型Maps的性能可能会非常糟糕。

// (new map can be initialized to better value to avoid resizing)
Map<OccupancyType, BigDecimal> filteredMap = new HashMap<>(roomPrice.size());
for (OccupancyType key: policy) {
    // contains() and get() can usually be combined
    if (roomPrice.contains(key)) {
       filteredMap.put(key, roomPrice.get(key));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接