转换集合<list <t>&gt;到2D数组T [] [] </list <t>

时间:2012-12-22 16:30:38

标签: java

  

可能重复:
  Convert ArrayList into 2D array containing varying lengths of arrays

如何将Collection<List<Foo>>转换为Foo[][]类型的2D数组?

我正在尝试使用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的类型应该是什么?

3 个答案:

答案 0 :(得分:3)

.toArray只能将集合转换为List<Foo>[]。您需要再次对列表数组的每个元素调用.toArray才能真正获得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]);
    }

答案 1 :(得分: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”方法很方便,但由于Generic类型,我通常觉得使用它很令人沮丧。像这样的实用方法通常更容易阅读并避免遇到的问题。

编辑:我应该注意:你需要知道或投射T.它会产生一个未经检查的类型异常(当然这是未经检查的!)。

答案 2 :(得分: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. 该函数是通用的,因此可以处理任何类型的引用类型(遗憾的是,intlong等本机类型需要更多工作。)
  3. 您传入的目标数组甚至可以预先分配到一定的大小,其行为与Collection.toArray完全相同。
  4. 该函数可以容忍同时更改其大小的集合(只要集合本身可以容忍)。
  5. 转换是类型安全的类型严格。
  6. 更多例子:

    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]]