2

我正在编写一个代码,其中包含以下几行:

 public static int[] toArray(List<Integer> list) {
   int[] array = new int[list.size()];
   for(int i = 0; i < array.length; i++)
     array[i] = list.get(i);
   return array;
 }
 public static double[] toArray(List<Double> list) {
   double[] array = new double[list.size()];
   for(int i = 0; i < array.length; i++)
     array[i] = list.get(i);
   return array;
 }
 public static String[] toArray(List<String> list) {
   String[] data = new String[list.size()];
   for(int i = 0; i < data.length; i++)
     data[i] = list.get(i);
   return data;

编译时出现以下错误:

error: name clash: toArray(List<Double>) and toArray(List<Integer>) have the same erasure
 public static double[] toArray(List<Double> list) {
                        ^
error: name clash: toArray(List<String>) and toArray(List<Integer>) have the same erasure
 public static String[] toArray(List<String> list) {
                        ^
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors

这个程序是我最近下载的一个开源程序(有点旧,2006 年)。在包中,我可以找到二进制版本和源代码。这意味着这段代码已经正确编译,但现在我无法编译它。

现在我有两个问题:

  1. 这种重载有什么问题?
  2. 我该如何解决这个问题?我可以用基于模板的函数替换这些函数吗?如果是这样,怎么做?

谢谢

4

4 回答 4

3

由于类型擦除而发生名称冲突。

另一方面,您可能根本不需要这些方法,因为您可以List.toArray直接使用该方法。

例如:

List<Double> myList = new ArrayList<Double>();
Double[] myArray = myList.toArray(new Double[]{});
于 2013-06-28T07:34:41.097 回答
3

使方法通用:

 public static T[] toArray(List<T> list) {
   T[] data = new T[list.size()];
   for(int i = 0; i < data.length; i++)
     data[i] = list.get(i);
   return data;

可能在语法上不正确,因为我写了 java 有一段时间了 :) 解决方案应该成立

于 2013-06-28T07:28:50.510 回答
2

看起来您的代码最初是为 Java 4 或更低版本编写的。

不要打扰自己,List已经有这样的方法,就用那个。

对于String,至少。对于原始类型,您不能这样做(类型参数不能代表原始类型)。您必须自己编写具有不同名称的方法,因为在运行时List<X>会变成Listfor whatever X。这称为类型擦除。

这意味着您的所有toArray方法都确实有一个toArray(List). 因此,创建toIntArray(),toDoubleArray()等...

或者只使用具有以下特性的番石榴:

否则,自己编写代码很容易:

int[] toIntArray(final Collection<? extends Number> c)
{
    final int[] ret = new int[c.size()];
    int i = 0;
    for (final Number n: c)
        ret[i++] = n.intValue();
    return ret;
}

double对等做同样的事情。

于 2013-06-28T07:34:57.763 回答
0

如果要从其包装器类型的相应列表转换原始数组,则可以使用Apache common's ArrayUtils#toPrimitive

例如:

int[] intArray = ArrayUtils.toPrimitive(list.toArray(new Integer[list.size()]));
于 2013-06-28T07:44:00.590 回答