Как преобразовать вложенный список в многомерный массив? - PullRequest
1 голос
/ 17 декабря 2009

В Java я хочу преобразовать вложенный List, который на самом глубоком уровне содержит унифицированный тип, в многомерный массив этого типа. Например, ArrayList<ArrayList<ArrayList<ArrayList<String>>>> в String[][][][]. Я пробовал несколько вещей, и я могу получить только массив объектов, таких как Object[][][][]. Для «простых списков» кажется, что Apache Commons Lang выполняет свою работу, но я не могу разобраться с вложенными делами.

Обновление:

Чтобы получить многомерный массив типа Object, я использую рекурсивную функцию, поэтому не могу установить тип ключа с помощью toArray (), см. Выдержку:

// the argument of this function is a (nested) list
public static Object convert(Object object) {

    Object[] result = null;
    List list = (List) object;
    if (list != null) {

        Object type = getElementType(list);
        if (type instanceof List) {

            int size = list.size();
            result = new Object[size];
            for (int counter = 0; counter < size; counter++) {

                Object element = list.get(counter);
                result[counter] = (element != null) ? convert(element) : null;
            }
        } else {
            result = list.toArray();
        }
    }

    return result;
}

private static Object getElementType(List list) {

    Object result = null;
    for (Object element : list) {
        if (element != null) {

            result = element;
            break;
        }
    }

    return result;
}

Ответы [ 4 ]

3 голосов
/ 17 декабря 2009

Чтобы создать любой тип массива, отличного от Object, необходимо передать ключ типа методу toArray. Это связано с тем, что для универсальных типов (например, ArrayList) аргумент типа стер (поэтому во время выполнения ArrayList<String> обрабатывается как обычный ArrayList), тогда как для массивов тип нет.

Похоже, у вас уже отсортировано создание массива Object, так что с этим и использованием ключа типа, я думаю, вы все отсортированы! : -)

1 голос
/ 21 декабря 2009

Это способ, который кто-то предложил решить для типа String. Cast2(List<?>) возвращает многомерный массив. Можно обобщить использование типа класса в качестве параметра. Спасибо за ваши комментарии.

static int dimension2(Object object) {

    int result = 0;
    if (object instanceof List<?>) {

        result++;
        List<?> list = (List<?>) object;
        for (Object element : list) {
            if (element != null) {
                result += dimension2(element);
                break;
            }
        }
    }

    return result;
}


static Object cast2(List<?> l) {

    int dim = dimension2(l);
    if (dim == 1) {
        return l.toArray(new String[0]);
    }

    int[] dims = new int[dimension2(l)];
    dims[0] = l.size();
    Object a = Array.newInstance(String.class, dims);
    for (int i = 0; i < l.size(); i++) {

        List<?> e = (List<?>) l.get(i);
        if (e == null) {
            Array.set(a, i, null);
        } else if (dimension2(e) > 1) {
            Array.set(a, i, cast2(e));
        } else {
            Array.set(a, i, e.toArray(new String[0]));
        }
    }
    return a;
}
0 голосов
/ 20 января 2010

Вы можете использовать transmorph :

ArrayList<ArrayList<ArrayList<ArrayList<String>>>> arrayList = new ArrayList<ArrayList<ArrayList<ArrayList<String>>>>();

/// populate the list ...
[...]    

Transmorph transmorph = new Transmorph(new DefaultConverters());
String[][][][] array = transmorph.convert(arrayList, String[][][][].class);
0 голосов
/ 17 декабря 2009

хе-хе, вот тоже ответ, но я не знаю, поможет ли это:

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

    public static void main(String[] args) throws MalformedURLException, IOException, SecurityException, NoSuchFieldException {

        Type t = ((ParameterizedType)(jdomTEst.class.getDeclaredField("x").getGenericType())).getActualTypeArguments()[0];  
        int[] dims = new int[t.toString().split("List").length];
        Object finalArray = Array.newInstance(String.class,  dims);

        System.out.println(finalArray);

    }

это печатает: [[[[Ljava.lang.String; @ 4e82701e

выглядит довольно грязно, но я люблю размышления :) 1006 *

...