使arrayList.toArray()返回更具体的类型

230

通常情况下,ArrayList.toArray() 的返回类型是 Object[]。但如果这个 ArrayList 是由对象 Custom 组成的,我该如何使 toArray() 返回类型为 Custom[] 而不是 Object[] 呢?


1
ArrayList中有两个同名方法'toArray()'。从1.5开始,第二个方法采用了类型化数组。您是否正在寻找1.5之前的解决方案? - Ritesh
相关链接:https://dev59.com/j3VC5IYBdhLWcg3w0EsD - tkruse
6个回答

355

像这样:

List<String> list = new ArrayList<String>();

String[] a = list.toArray(new String[0]);

在Java6之前,建议编写以下代码:

String[] a = list.toArray(new String[list.size()]);

因为内部实现会重新分配一个适当大小的数组,所以最好提前这样做。从Java6开始,推荐使用空数组,请参见.toArray(new MyClass [0])或.toArray(new MyClass [myList.size()])?

如果列表类型不正确,则需要在调用toArray之前进行强制转换。像这样:

    List l = new ArrayList<String>();

    String[] a = ((List<String>)l).toArray(new String[l.size()]);

1
据我所知:这与Java作为一个整体有关,无法使用通用构造函数。因此,虽然它知道您需要将其转换为诸如String[]或MyObject[]之类的对象,但它无法自行实例化它。 - user1499731
如果我们想使用double而不是String,该怎么办?它似乎会失败... 我们可以使用Double,但是如果我要使用double呢? - user1300214
2
@pbs 你不能这样做。Java的泛型只支持引用类型,不支持原始类型。自动装箱/拆箱应该让你在大多数情况下忽略它们之间的差异。 - solarshado
1
我总是使用这个语法:.toArray(new String[]{}) - arnonuem

23

将List转换为特定类型(例如Long)的数组的简化版本:

Long[] myArray = myList.toArray(Long[]::new);

(自Java 11起可用)


3
这个程序在哪个Java版本中运行?我认为在Java 8中是不合法的...或者对于复杂类型无效。 - user1445967
没问题,你的答案完全正确。我的组织使用较旧的Java版本。 - user1445967
我认为它从Java 11可用。 - giltsl

16

它实际上不一定需要返回Object[],例如:

    List<Custom> list = new ArrayList<Custom>();
    list.add(new Custom(1));
    list.add(new Custom(2));

    Custom[] customs = new Custom[list.size()];
    list.toArray(customs);

    for (Custom custom : customs) {
        System.out.println(custom);
    }

这是我的Custom类:

public class Custom {
    private int i;

    public Custom(int i) {
        this.i = i;
    }

    @Override
    public String toString() {
        return String.valueOf(i);
    }
}


2
 public static <E> E[] arrayListToTypedArray(List<E> list) {

    if (list == null) {
      return null;
    }
    int noItems = list.size();
    if (noItems == 0) {
      return null;
    }

    E[] listAsTypedArray;
    E typeHelper = list.get(0);

    try {
      Object o = Array.newInstance(typeHelper.getClass(), noItems);
      listAsTypedArray = (E[]) o;
      for (int i = 0; i < noItems; i++) {
        Array.set(listAsTypedArray, i, list.get(i));
      }
    } catch (Exception e) {
      return null;
    }

    return listAsTypedArray;
  }

2
如果我们有一个包含继承自Animal的Dog和Cat类型的ArrayList<Animal>,那该怎么办呢?如果第一个元素是Dog,下一个是Cat,似乎会失败。它看到第一个元素,创建了一个Dog类型的数组,添加了狗,然后尝试添加猫并失败了。这也可能不适用于泛型E。 - ptoinson
1
这是唯一一个回答该问题的答案。而且它可行。唯一的注意事项是关于多态性的备注,但对于我们其他人来说,做JSON相关的事情,它完全可以正常工作。 - Victor Ionescu

1
我得到了答案...这似乎完美地运作。
public int[] test ( int[]b )
{
    ArrayList<Integer> l = new ArrayList<Integer>();
    Object[] returnArrayObject = l.toArray();
    int returnArray[] = new int[returnArrayObject.length];
    for (int i = 0; i < returnArrayObject.length; i++){
         returnArray[i] = (Integer)  returnArrayObject[i];
    }

    return returnArray;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接