使函数返回与input-type相同的输出类型

时间:2015-07-13 19:07:49

标签: java generics

所以,让我们说我有以下通用函数来对任何Collection中的元素进行排序(例如ArrayList<T>HashSet<T>):

public static <T extends Comparable> Collection<T> sort(Collection<T> a)
{
    List<T> l = a.stream().sorted().collect(Collectors.toList());
    return l;
}

问题在于,当我使用以下代码调用函数时,我有一个类型ArrayList<Integer>的现有变量,它有一些值:

counts = (ArrayList<Integer>) sort(counts);

调用函数时,我必须将返回的Collection转换为ArrayList。

有没有办法让sort函数为我做这个转换?因此,如果输入为ArrayList,则输出为ArrayList;如果输入是HashSet,则输出为HashSet等......

4 个答案:

答案 0 :(得分:3)

你需要在答案中使用@ 6ton建议的泛型,但你还需要为Supplier方法指定sort,这样就可以创建正确的Collector

public static <T extends Comparable<T>, E extends Collection<T>> E sort(
    Collection<T> a, 
    Supplier<E> factory) {

    return a.stream().sorted().collect(Collectors.toCollection(factory));
}

然后,以这种方式使用您的sort方法:

List<Float> ordered = sort(unordered, ArrayList::new);

这将返回ArrayList,但请注意第一个参数(我称之为unordered)可以是任意Collection,即HashSetTreeSet等。同样,您可以返回Set,而unordered可以是List或其他Collection

Set<Float> ordered = sort(unordered, LinkedHashSet::new);

注意:正如其他人所说,对HashSet进行排序没有意义,其他一些集合也是如此。虽然将Supplier指定为返回的Collection的工厂不会产生运行时错误,但并不意味着返回的Collection将始终排序。例如:

Set<Float> stillUnordered = sort(unordered, HashSet::new);

在这种情况下,流将收集到HashSet,而{{1}}不会维持订单。

答案 1 :(得分:-1)

一种方法是覆盖你的方法,就像我在下面所做的那样。如果您希望这种方便的类型有限,这将有效。如果您需要更多类型,Collection(或List)将是一个捕获。

public static <T extends Comparable> Collection<T> sort(Collection<T> a)
{
    // do something;
    return a;
}

public static <T extends Comparable> HashSet<T> sort(HashSet<T> a)
{
    return (HashSet<T>)sort(a);
}

public static <T extends Comparable> ArrayList<T> sort(ArrayList<T> a)
{
    return (ArrayList<T>)sort(a);
}

答案 2 :(得分:-1)

  

有没有办法让sort函数为我做这个转换?因此,如果输入是ArrayList,则输出是ArrayList;如果输入是HashSet,则输出是HashSet等......

你无法做到这一点,期间。无法订购<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

因此,鉴于您无法排序的集合,您必须将特定集合作为返回类型。

答案 3 :(得分:-4)

您可以将方法定义为

public static <T extends Comparable<T>, E extends Collection<T>> E sort(Collection<T> a) {
    //return ...;
}

然后像这样调用它:

ArrayList<Integer> arrayList = new ArrayList<>();
ArrayList<Integer> sortedList = sort(arrayList);
相关问题