make arrayList.toArray () возвращает более конкретные типы

189

Итак, обычно ArrayList.toArray()возвращает тип Object[].... но предполагается, что это Arraylistобъект Custom, как мне сделать, toArray()чтобы вернуть тип, Custom[]а не Object[]?

kamikaze_pilot
источник
1
В ArrayList есть 2 метода с одинаковым именем toArray (). Начиная с 1.5, второй метод принимает типизированный массив. Вы ищете решение для pre-1.5?
Ритеш
Связанный: stackoverflow.com/questions/174093
tkruse

Ответы:

308

Как это:

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
AFAIK: Это как-то связано с Java в целом, поскольку он не может использовать универсальные конструкторы. Поэтому, хотя он знает, что он вам нужен для преобразования вас в объект типа String [] или MyObject [], он не может создать его экземпляр самостоятельно.
Что если вместо String мы хотим использовать double? Кажется, что не получается ... Мы можем использовать Double, но что, если я хочу двойной?
Пиксель
2
@pbs Ты не можешь. Обобщения Java поддерживают только ссылочные типы, а не примитивы. Автобокс / распаковка должны позволять вам игнорировать разницу между ними по большей части.
solarshado
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);
    }
}
LIMC
источник
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;
}
Ashvitha
источник
0
@SuppressWarnings("unchecked")
    public static <E> E[] arrayListToArray(ArrayList<E> list)
    {
        int s;
        if(list == null || (s = list.size())<1)
            return null;
        E[] temp;
        E typeHelper = list.get(0);

        try
        {
            Object o = Array.newInstance(typeHelper.getClass(), s);
            temp = (E[]) o;

            for (int i = 0; i < list.size(); i++)
                Array.set(temp, i, list.get(i));
        }
        catch (Exception e)
        {return null;}

        return temp;
    }

Образцы:

String[] s = arrayListToArray(stringList);
Long[]   l = arrayListToArray(longList);
Али Багери
источник
1
Что если у нас есть ArrayList <Animal> и он содержит типы Dog и Cat, расширяющие Animal? Похоже, что он потерпит неудачу, если первый элемент - Dog, а следующий - Cat. Он видит первый элемент, создает массив типа Dog, добавляет собаку, затем пытается добавить кошку и терпит неудачу. Также может не работать с дженериком Е.
ptoinson