集合初始化的通用方法

集合初始化的通用方法

问题描述:

我想创建一个通用方法来组合集合。集合初始化的通用方法

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

但我得到的编译错误:

Wildcard type '?' cannot be instantiated directly

+0

或者使用番石榴的'Sets.union()'。 – chrylis

+0

我不喜欢使用外部库。 –

使用泛型类型参数,而不是通配符:

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

谢谢,它的工作原理:D –

+0

编辑说明? –

+0

@Code.IT创建一个HashSet的匿名子类的实例没有任何理由对我来说没有意义。 – Eran

你的错误发生,因为编译器无法保证?为您传回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); 
+0

这不包含Collections.unmodifiableSet(); –

+0

你需要它吗?你的问题并不清楚。你总是可以将最后一行写入'返回Collections.unmodifiableSet(toReturn);'。 –

+0

只是评论,它不等于我的问题 –