所以我有以下HashMap:根據某些規範創建HashMap的子集?
HashMap<String, List<someDataType>> map
;
我想創建一個新的HashMap,它只包含map
中的k/v對,其長度小於某個「x」的值(列表)。我知道如何做到這一點的唯一方法是遍歷HashMap並將k/v對放入新的HashMap中。有沒有一種更簡潔的方式來實現我在找的東西?謝謝。
所以我有以下HashMap:根據某些規範創建HashMap的子集?
HashMap<String, List<someDataType>> map
;
我想創建一個新的HashMap,它只包含map
中的k/v對,其長度小於某個「x」的值(列表)。我知道如何做到這一點的唯一方法是遍歷HashMap並將k/v對放入新的HashMap中。有沒有一種更簡潔的方式來實現我在找的東西?謝謝。
使用番石榴:
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擊敗我 - 但請注意,「filterEntries」只會返回基礎地圖的過濾*視圖*,以防OP想要複製它。 'filterValues'會更簡潔。 –
承認使用番石榴,是不是'ArrayListMultiMap'和'MultiMaps.filterkeys'更適合? 'MultpMaps.filterValues'或'.filterEntries'不起作用,因爲你得到每個單獨的值或鍵值對。 –
或者,您可以製作原始貼圖的副本,然後遍歷這些值,以消除長度小於x的值。
如果Guava庫是提供給你的項目,你可以使用Maps.filterValues
(有點呼應基思的答案):
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
返回原始地圖的過濾視圖。
更新:與Java 8你能夠簡化謂詞lambda表達式:
Map<String, List<String>> filteredMap = Maps.filterValues(map, list -> list.size() < x);
你可能想看看從谷歌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);
我相信你能找到的東西在裏面,可以做你找什麼:-)
當我開始寫這篇文章的時候,沒有答案......當我提交的時候,有兩個人認識番石榴比我更好! :-O – Stewart
與其他番石榴例子一起去,你可以用番石榴的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
而不是使用匿名內部類的靜態內部類。
不是我所知道的。 – jlordo
您將不得不在地圖上保留額外的約束,以便不必遍歷整個地圖。例如,如果您的地圖按列表長度升序排列,那麼您可以循環播放,直到看到長度爲1的x以外的地方。 –
@HunterMcMillen:你知道一個基於值排序的地圖嗎? – jlordo