我想创建一个通用方法来组合集。
public class CollectionsHelper {
public static Set<?> combineSets(Set<?> set1, Set<?> set2){
return Collections.unmodifiableSet(new HashSet<?>() {{
addAll(set1);
addAll(set2);
}});
}
}
但是我得到了编译错误:
通配符类型&#39;?&#39;无法直接实例化
答案 0 :(得分:7)
使用泛型类型参数代替通配符:
public static <T> Set<T> combineSets(Set<T> set1, Set<T> set2)
{
return Collections.unmodifiableSet(new HashSet<T>() {{
addAll(set1);
addAll(set2);
}});
}
第二个想法,我不会使用匿名的HashSet
子类实例。我更喜欢:
public static <T> Set<T> combineSets(Set<T> set1, Set<T> set2)
{
HashSet<T> set = new HashSet<>(set1);
set.addAll (set2);
return Collections.unmodifiableSet(set);
}
答案 1 :(得分:2)
您的错误正在发生,因为编译器无法保证您返回的?
的{{1}}是Set<?>
类型中的?
类型的超类型两个Set<?>
个参数。
您想要的是一种通用方法。 type参数必须是您在集合中使用的两种类型的超类型。你可以这样做。
public static <E> Set<E> combineSets (Set<? extends E> set1, Set<? extends E> set2) {
Set<E> toReturn = new HashSet<E>();
toReturn.addAll(set1);
toReturn.addAll(set2);
return toReturn;
}
? extends E
部分很重要。这表示set1
和set2
不必是Set<E>
- 它们可以是E
的任何子类的集合。然后,类型推断将使E
成为两种类型中最低的超类。
如果您确实需要将其设置为不可修改的设置,请将最后一行更改为
return Collections.unmodifiableSet(toReturn);