所以我有以下HashMap:
HashMap<String, List<someDataType>> map
;
我想创建一个新的HashMap,它只由map
中的k / v对组成,它们的值(列表)长度小于某个“x”。我知道如何做到这一点的唯一方法是遍历HashMap并将k / v对放入新的HashMap中。有没有更简洁的方法来实现我正在寻找的东西?感谢。
答案 0 :(得分:8)
使用guava:
Map<String, List<String>> newMap =
Maps.filterEntries(originalMap, new MyEntryPredicate(10));
其中:
private static class MyEntryPredicate implements Predicate<Map.Entry<String, List<String>>> {
// max list length, exclusive
private int maxLength;
private MyEntryPredicate(int maxLength) {
this.maxLength = maxLength;
}
@Override
public boolean apply(Map.Entry<String, List<String>> input) {
return input != null && input.getValue().size() < maxLength;
}
}
答案 1 :(得分:4)
如果您的项目可以使用Guava库,则可以使用Maps.filterValues
(有点回应Keith的回答):
final int x = 42;
Map<String, List<String>> filteredMap =
Maps.filterValues(map, new Predicate<Collection<?>>() {
@Override
public boolean apply(final Collection<?> collection) {
return collection.size() < x;
}
});
Map<String, List<String>> filteredMapCopy = ImmutableMap.copyOf(filteredMap);
请注意需要复制,因为filterValues
会返回原始地图的已过滤视图。
更新:,您可以将谓词简化为lambda表达式:
Map<String, List<String>> filteredMap = Maps.filterValues(map, list -> list.size() < x);
答案 2 :(得分:1)
现在(Java 8+)可以使用流来完成:
Predicate<Map.Entry<String, List<String>>> test = entry -> entry.getValue().size() <= x; // note this is java.util.function.Predicate
Map<String, List<String>> filteredMap = map.entrySet().stream().filter(test)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
这有助于避免对番石榴的依赖,这可能是不希望的。
答案 3 :(得分:0)
或者,您可以复制原始地图并迭代删除长度小于x的值。
答案 4 :(得分:0)
您可能需要查看Google的Guava库。那里有大量的Collections
和Map
相关工具,可以让你非常简洁地完成复杂的工作。您可以做的一个例子是:
Iterable<Long> list =
Iterables.limit(
Iterables.filter(
Ordering.natural()
.reverse()
.onResultOf(new Function<Long, Integer>() {
public Integer apply(Long id) {
return // result of this is for sorting purposes
}
})
.sortedCopy(
Multisets.intersection(set1, set2)),
new Predicate<Long>() {
public boolean apply(Long id) {
return // whether to filter this id
}
}), limit);
我相信你可以在那里找到一些可以做你正在寻找的东西: - )
答案 5 :(得分:0)
与其他Guava示例一起,您可以使用Guava的MultiMap
s:
final MultiMap<K, V> mmap = ArrayListMultiMap.create();
// do stuff.
final int limit = 10;
final MultiMap<K, V> mmapView =
MultiMaps.filterKeys(mmap, new Predicate<K>(){
public boolean apply(K k) {
return mmap.get(k).size() <= limit;
}
});
MultiMaps.newListMultiMap
方法接受您不想提供的参数。您不能在此处使用MultiMaps.filterValues
或.filterEntries
,因为它们使用的是单个值,而不是值列表。另一方面,mmap.get(k)
永远不会返回null
。当然,您可以使用传递mmap
和limit
的静态内部类,而不是使用匿名内部类。