我有兩個地圖引數:Map<X,Set<Y>> map1和Map<X,Set<Y>> map2.
我正在尋找一種方法來撰寫一種方法,該方法生成一個新映射,其中包含兩個映射中都存在的鍵的值的交集,以及存在于或中的鍵的值的聯合。map1map2
換句話說,對于任何X x如果它在 的域中map1但不在 的域中map2,那么它的值將是map1.get(x)。在相反的情況下也一樣。如果它在它們兩個中,那么我想回傳一個集合,它是 和 的map1.get(x)交集map2.get(x)。
假設我知道哪個類X是,這可以通過以下代碼完成:
public Map<X,Set<Y>> unifyAndIntersect(Map<X,Set<Y>> map1, Map<X,Set<Y>> map2) {
Map<X,Set<Y>> combined = new HashMap();
combined.putAll(map1);
for(X x : map2.keySet()){
if(combined.contains(x)){
Set<Y> res = Sets.newSet();
res.addAll(map1.get(x));
res.retainAll(map2.get(x));
combined.put(x,res);
}
else{
combined.put(x,map2.get(x));
}
}
}
但是,我想讓這個方法通用,從某種意義上說它適用于任何Xand Y。我嘗試過使用Object,但從我的型別別轉換為Object...時出錯
你能告訴我什么是正確的方法嗎?
uj5u.com熱心網友回復:
為了宣告一個泛型方法,您需要<X,Y>在方法修飾符和回傳型別之間提供泛型型別引數(有關更多資訊,請參閱)。沒有它X并且Y在映射型別Map<X,Set<Y>>中不會被視為型別的通用“占位符”,而是作為型別本身和編譯器會抱怨該型別X并且Y是未知的。
不要忘記右側的菱形 <>new HashMap();,在實體化泛型類時,沒有菱形會創建行型別的映射。
您提供的代碼中也存在不一致:如果兩個映射都存在一個鍵,則會將一個新集合作為值添加到結果映射中,但是如果根據您的代碼鍵僅包含在其中一個中將使用現有的集合。我最好確保對結果映射的值的后續修改不會對狀態產生影響,map1并map2為每個值生成一個新集合。
public <X,Y> Map<X, Set<Y>> unifyAndIntersect(Map<X,Set<Y>> map1,
Map<X,Set<Y>> map2) {
Map<X, Set<Y>> combined = new HashMap<>();
for(Map.Entry<X, Set<Y>> entry: map1.entrySet()){
Set<Y> union = new HashSet<>(entry.getValue());
if (map2.containsKey(entry.getKey())) {
union.retainAll(map2.get(entry.getKey()));
}
combined.put(entry.getKey(), union);
}
return combined;
}
使用 Stream API 可以實作相同的邏輯:
public <X,Y> Map<X, Set<Y>> unifyAndIntersect(Map<X,Set<Y>> map1,
Map<X,Set<Y>> map2) {
return map1.entrySet().stream()
.map(entry -> {
Set<Y> set2 = map2.get(entry.getKey());
return set2 == null ? Map.entry(entry.getKey(), new HashSet(entry.getValue())) :
Map.entry(entry.getKey(),
entry.getValue().stream()
.filter(set2::contains)
.collect(Collectors.toSet()));
})
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/483534.html
上一篇:如何在Go中模擬“fmap”?
