简体   繁体   English

如何在Sets.powerSet中使用通配符泛型

[英]How to use wildcard generics with Sets.powerSet

I have some code like this 我有一些这样的代码

import com.google.common.collect.Sets;
public void handleInput(Set<Object> conditions){
    Set<Set<Object>> powerSet = Sets.powerSet(conditions);
    ...
}

This works fine. 这很好。 But I want to do this: 但我想这样做:

public void handleInput(Set<? extends Object> conditions){
    Set<Set<? extends Object>> powerSet = Sets.powerSet(conditions);
    ...
}

so I can get the powerset of objects that are subclasses of object. 因此我可以获得作为对象子类的对象的功率集。 But this won't compile and I get the error: 但这不会编译,并且出现错误:

Type mismatch: cannot convert from Set<Set<capture#1-of 
? extends Object>> to Set<Set<? extends Object>>

How can I achieve this goal? 我怎样才能实现这个目标?

EDIT: I guess it has something to do with the generic type getting erased at compile time, so that the compiler can't know that powerSet won't add something illegal to the sets it's creating. 编辑:我想这与在编译时被删除的通用类型有关,以便编译器无法知道powerSet不会在其创建的集合中添加非法内容。 I've reworked the client, by casting all the inputs to Object, and removing the wildcard altogether. 通过将所有输入转换为对象并完全删除通配符,我对客户端进行了重新设计。 Is this the best way? 这是最好的方法吗? Thanks! 谢谢!

In this case it doesn't make any sense - since all Java classes extend java.lang.Object at some point. 在这种情况下,它没有任何意义-因为所有Java类都在某个时候扩展了java.lang.Object So ? extends Object ? extends Object ? extends Object is redundant. ? extends Object是多余的。

But speaking of Sets.powerSet , this works like a charm: 但是说到Sets.powerSet ,它就像一个魅力:

public class TestClass {

    public static class A {}

    public static class B extends A {}

    public static class C extends B {}


    public Set<? extends Set<? extends A>> exampleMethod(Set<? extends A> input) {
        return Sets.powerSet(input);
    }

    public static void main(String[] args) {
        final TestClass testClass = new TestClass();
        final A a = new A();
        final B b = new B();
        final C c = new C();

        System.out.println(
            testClass.exampleMethod(
                    ImmutableSet.of(a, b, c)
            )
        );
    }

}

as @slnowak notes, when you are extending Object, the code is really redundant. 如@slnowak所述,在扩展Object时,代码确实是多余的。

However, to understand the Exception and avoid it... 但是,要了解该异常并避免它...

public void handleInput(Set<? extends Object> conditions){
    Set<? extends Set<? extends Object>> powerSet = Sets.powerSet(conditions);
    ...
}

this will compile and, more usefully, you can restrict the types in your conditions argument using this method, for instance - you could have: 这将进行编译,并且更有用的是,例如,您可以使用此方法限制条件参数中的类型-您可以:

public void handleInput(Set<? extends Number> conditions){
    Set<? extends Set<? extends Number>> powerSet = Sets.powerSet(conditions);
    ...
}

and this would prevent you passing in sets that had non-numeric types and warn you of this at compile time. 这样可以防止您传入具有非数字类型的集合,并在编译时警告您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM