生成一个包含两个地图映射中包含的值相交/联合的地图,x,set< y>

发布于 2025-02-03 08:37:01 字数 1231 浏览 3 评论 0原文

我有两个地图参数:map< x,set< y>> map1map< x,set< y>> MAP2

我正在寻找一种编写一种方法,该方法将生成 value的相交的新映射 value 这两个地图中都存在,值的A Union map1或<代码> map2 。

换句话说,对于任何x x,如果它在map1的域中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));
          }
    }
}

但是,我想使此方法通用,从某种意义上说,它将适用于任何x 和y。我尝试使用对象,但是要获得从我的类类型转换为对象的错误...

您能告诉我什么是正确的方法?

I have two map arguments: Map<X,Set<Y>> map1 and Map<X,Set<Y>> map2.

I am looking for a way to write a method that generates a new map containing an Intersection of values for keys that are present in both maps, and a Union of values for keys that are present either in map1 or map2.

In other words, for any X x if it is in the domain of map1 but not in the domain of map2, then its value will be map1.get(x). Same in the opposite case. If it is in both of them, then I would like to return a set that is the intersection of map1.get(x) and map2.get(x).

Assuming I know which class X is, this can be done with the following code:

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));
          }
    }
}

However, I would like to make this method generic, in a sense that it will work for any X and Y. I have tried using Object, but get an error converting from my class type to Object...

Could you advise me on what is the correct way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ペ泪落弦音 2025-02-10 08:37:01

为了声明一种通用方法,您需要在方法修饰符和返回类型之间提供通用类型参数&lt; x,y&gt; 有关更多信息,请参见 )。如果没有那个xy在地图类型map&lt; x中类型,但是由于类型本身和编译器会抱怨类型xy是未知的。

不要忘记”代码>&lt;&gt; 在右侧,实例化通用类时,new Hashmap();没有钻石的创建 row 类型。

您提供的代码也存在不一致之处:如果存在密钥,则两个映射a new set 将以值添加为一个值,但是如果仅在一个中包含键根据您的代码,将使用现有集合。我最好确保通过为每个值生成一个新集合,对所得映射值的后续修改将不会影响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;
}

可以使用流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));
}

In order to declare a generic method, you need to provide generic type parameters <X,Y> between method modifiers and return type (for more information, see). Without that X and Y in the map type Map<X,Set<Y>> would not be treated as generic "placeholders" for types, but as types itself and the compiler will complain that types X and Y are unknown.

Don't forget the diamond <> on the right side, while instantiating a generic class, new HashMap(); without a diamond creates a map of row type.

There's also an inconsistency in the code you've provided: if a key is present is both maps a new set would be added as a value into the resulting map, but if the key is contained only in one of them according to your code an existing set would be used. I would better to ensure that subsequent modifications of the values of the resulting map will have no impact on the state of map1 and map2 by generating a new set for every value.

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;
}

The same logic can be implemented using 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));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文