2

可能重复:
将 ArrayList 转换为包含不同长度数组的二维数组

如何将 aCollection<List<Foo>>转换为类型的二维数组Foo[][]

我正在尝试使用该toArray方法,但我不确定语法。例如,这不起作用:

import com.google.common.collect.Collections2;
Collection<List<Foo>> permuted = Collections2.permutations(bar);
Foo[][] permutedArray = permuted.toArray(new Foo[10][10]);//exception here

它在扔ArrayStoreException。在这种情况下,类型应该是什么permutedArray

4

3 回答 3

3

.toArray只能将集合转换为List<Foo>[]. 您需要再次调用.toArraylist 数组的每个元素才能真正获得Foo[][].

    @SuppressWarnings("unchecked")
    final List<Foo>[] permutedList = permuted.toArray(new List[10]);
    final Foo[][] permutedArray = new Foo[10][10];
    for (int j = 0; j < 10; ++j) {
        permutedArray[j] = permutedList[j].toArray(new Foo[10]);
    }
于 2012-12-22T16:50:15.230 回答
1

这似乎做一组嵌套循环可能更有意义:

//Untested, I might have made some silly mistake
T[][] array = new T[collection.size()[];
int collection = 0;
int list = 0;

for(List<T> list : collection)
{
  list = 0;
  array[collection] = new T[list.size()];
  for(T t : list)
    array[collection][list++] = t;

  collection++;
}

“toArray”方法很方便,但由于泛型类型,我通常觉得使用起来很沮丧。像这样的实用方法通常更容易阅读并避免您遇到的问题。

编辑:我应该注意:您需要知道或强制转换 T。它会生成一个未经检查的类型异常(这当然是未经检查的!)。

于 2012-12-22T17:03:09.097 回答
0

如果您尝试以下通用实用程序函数会怎样:

public static <T> T[][] asMatrix(
    Collection<? extends Collection<? extends T>> source,
    T[][] target) {

    // Create a zero-sized array which we may need when converting a row.
    @SuppressWarnings("unchecked") T[] emptyRow =
        (T[])Array.newInstance(target.getClass().getComponentType().getComponentType(), 0);

    List<T[]> rows = new ArrayList<T[]>(source.size());
    int i = 0;
    for (Collection<? extends T> row : source) {
        T[] targetRow = i < target.length ? target[i] : null;
        rows.add(row.toArray(targetRow != null ? targetRow : emptyRow));
        i += 1;
    }
    return rows.toArray(target);
}

用法:

Collection<List<Foo>> permuted = ...;
Foo[][] result = asMatrix(permuted, new Foo[][] {});

它的工作方式是访问每个子集合(即行),将其转换为数组。我们将这些数组缓存在一个集合中。然后我们要求该集合将自己转换为一个数组,我们将其用作函数的结果。

这个效用函数的好处是:

  1. Collection.toArray用于所有的数组构造和复制。
  2. 该函数是通用的,因此可以处理任何类型的引用类型(不幸的是,像 , 等原生类型int需要long更多的工作)。
  3. 您传入目标数组,它甚至可能被预先分配到一定的大小,其行为与所做的完全相同Collection.toArray
  4. 该函数可以容忍同时改变其大小的集合(只要集合本身是可以容忍的)。
  5. 转换是类型安全类型严格的。

更多示例:

List<List<Integer>> list =
    Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));

Integer[][] result;

result = asMatrix(list, new Integer[][] {});
System.out.println(Arrays.deepToString(result));

result = asMatrix(list, new Integer[][] {new Integer[] {9, 9, 9, 9}, null});
System.out.println(Arrays.deepToString(result));

结果:

[[1, 2], [3, 4]]
[[1, 2, null, 9], [3, 4]]
于 2012-12-22T18:22:40.763 回答