我昨天在写作业时遇到了一个问题。我完成了作业,但是我仍然不太明白为什么我的代码可以工作。我必须编写一个排序函数,该函数将任何可比较的通用对象的可变参数作为参数并返回该参数。问题是我必须返回一个排序对象数组。因此,我不得不学习有关varargs列表和数组的更多信息。
该函数是这样定义的。
public <T extends Comparable<T>> T[] stableSort(T ... items)
在函数中,我列出了一个列表,我将对其进行排序并完成所有工作。
List<T> list = new ArrayList<T>(Arrays.asList(items));
在函数的结尾,我将列表返回给Array,以便它与输出类型T []相匹配。
list.toArray(items.clone());
我的问题是,因为我已经从varargs中创建了列表,所以为什么必须在toArray函数中执行items.clone()。这似乎对我做了两件事。我以为arrays.asList()会克隆要列出的array的值,但我不明白为什么要在toArray()的代码末尾再次做一次。我知道这是正确的编写方式,因为我昨天完成了作业,并从 class 论坛上找到了这种方式,但是我仍然不明白为什么。
编辑
该任务要求我用排序的文件创建一个新数组,然后返回它。由于类型擦除,如果不引用适合该泛型的类,则无法实例化泛型类型的数组。但是,varargs数组的类型为T,因此我应该克隆一个符合常规约束的类型的数组。我不知道该怎么做。因此,我决定使用清单来简化截止日期之前的时间。
最佳答案
我的问题是,因为我已经从varargs中列出了列表,为什么我必须要做items.clone()
你是对的。不幸的是,如果仅使用toArray()
方法,编译器将无法确定数组的类型。您应该会收到一个编译错误,提示无法从Object []转换为T []。需要调用item.clone()
来帮助编译器进行类型推断。另一种方法是说return (T[])list.toArray
就是说,我不推荐这两种方法。首先将数组转换为列表并将其转换回数组实际上没有任何意义。我看不到任何重要的收获,甚至您从这段代码中也无法理解。