初始化Set的通用方法

时间:2017-07-27 08:28:15

标签: java generics

我想创建一个通用方法来组合集。

public class CollectionsHelper {
    public static Set<?> combineSets(Set<?> set1, Set<?> set2){
        return Collections.unmodifiableSet(new HashSet<?>() {{
            addAll(set1);
            addAll(set2);
        }});
    }
}

但是我得到了编译错误:

  

通配符类型&#39;?&#39;无法直接实例化

2 个答案:

答案 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部分很重要。这表示set1set2不必是Set<E> - 它们可以是E的任何子类的集合。然后,类型推断将使E成为两种类型中最低的超类。

如果您确实需要将其设置为不可修改的设置,请将最后一行更改为

return Collections.unmodifiableSet(toReturn);