我正在尝试合并两组
a
和b
:
Set<? extends Element> a = getSetA();
Set<? extends Element> b = getSetB();
Set<? extends Element> c = new HashSet<>(a);
c.addAll(b);
但是我在最后一行收到此错误:
Required type: Collection<? extends capture of ? extends Element>
Provided: Set<capture of ? extends Element>
您遇到的错误源于在集合的泛型中使用通配符 (
? extends Element
)。当您声明 Set<? extends Element>
时,这意味着该集合可以包含 Element
子类的任何类型的元素,但确切的子类型未知。这会导致您可以对此类集合执行的操作受到限制,特别是在向其中添加元素或集合时。 Java编译器不允许添加未知泛型类型的集合,因为它无法确保编译时的类型安全。
但是,有一种方法可以通过使用具有有界类型参数的方法来实现您想要的目的。这种方法允许您捕获通配符类型并使用它以类型安全的方式组合集合。具体方法如下:
public static <T extends Element> Set<T> combineSets(Set<? extends T> a, Set<? extends T> b) {
Set<T> c = new HashSet<>(a);
c.addAll(b);
return c;
}
此方法使用
<T extends Element>
捕获通配符类型,并使用 T
作为新集合 c
的类型。这样,两个集合 a
和 b
都被视为类型 T
,并且您可以安全地将两个集合中的所有元素添加到集合 c
。以下是您可以如何使用此方法:
Set<Element> a = getSetA(); // Assuming this returns Set<? extends Element>
Set<Element> b = getSetB(); // Assuming this returns Set<? extends Element>
Set<Element> c = combineSets(a, b);
您无法向
Set<? extends Element>
添加元素。另请参阅生产者扩展消费者超级。 Set<? extends Element>
将成为 Element
的“生产者”。
完全没有必要将
c
声明为Set<? extends Element>
。它的类型可以是 Set<Element>
,那么 addAll
调用是有效的。
Set<? extends Element> a = getSetA();
Set<? extends Element> b = getSetB();
Set<Element> c = new HashSet<>(a);
c.addAll(b);
// if you really like Set<? extends Element>, feel free to:
Set<? extends Element> d = c;