如何在java中实现将泛型类型数组转换为泛型类型二维数组的函数?

时间:2010-11-18 02:31:27

标签: java arrays generics

public static <T> T[][] toTwoDim(T[] array)

上面的函数签名.. 它是一个通用的类型函数,无论数组中包含的数据是什么类型,都可以使用它。 通常,它接收一个数组,并返回一个二维数组,其半元素在第一行,另一半在第二行。 我不知道如何实现它因为我无法在函数内部创建泛型类型的二维数组。 有人帮帮我吗? 谢谢!

4 个答案:

答案 0 :(得分:1)

我玩了很多东西,而且出于类型擦除的原因,我的理解是这不是可能的

基于如何创建泛型类型参数数组的其他示例,似乎以下代码应该起作用,但最终只有在函数返回时才会失败,Object[][]无法转换为Integer[][]。它会早于失败,除了IIRC (T[][])的初始演员基本上在编译时删除并采取行动以防止警告,因此它没有真正的影响。

@SuppressWarnings("unchecked")
public static <T> T[][] toTwoDim(T[] array){
    int halflen = array.length / 2;

    T[][] foo = (T[][]) new Object[2][];

    foo[0] = (T[]) new Object[halflen];
    foo[1] = (T[]) new Object[halflen];

    for(int i = 0; i < halflen; i++){
        foo[0][i] = array[i];
        foo[1][i] = array[i+halflen];
    }

    System.out.println(Arrays.asList(foo[0]));
    System.out.println(Arrays.asList(foo[1]));

    return foo;
}

public static void main(String[] a){
    Integer[] bar = {1,2,3,4};
    Integer[][] foo = toTwoDim(bar);
    System.out.println(Arrays.asList(foo[0]));
}

答案 1 :(得分:1)

应该可以做到。

基本方法是使用java.lang.reflect.Array.newInstance(clazz, dimX, dimY)来创建数组实例。

  • 如果希望结果数组的基本类型与参数的基本类型相同,则使用反射从array.getClass()获取基本类型。

  • 如果您希望结果数组的基本类型为<T>,则需要向类型为toTwoDim的{​​{1}}添加额外参数,并将其用于传递所需数组基类型的类对象。 (类型擦除意味着Class<T>方法无法在运行时确定toTwoDim的类对象。将类对象作为参数传递是标准的解决方法。)

答案 2 :(得分:1)

我找到了完美的解决方案:

@SuppressWarnings("unchecked")
public static <T> T[][] toTwoDim(T[] array) {
    Class<T> ctype = (Class<T>) array.getClass().getComponentType();
    int halfLength = array.length / 2;
    T[][] ret = (T[][]) Array.newInstance(ctype, 2, 1);
    T[] r1 = (T[]) Array.newInstance(ctype, halfLength);
    T[] r2 = (T[]) Array.newInstance(ctype, array.length - halfLength);
    ret[0] = r1;
    ret[1] = r2;
    for (int i = 0; i < halfLength; i++)
        r1[i] = array[i];
    for (int i = 0; i < array.length - halfLength; i++) {
        r2[i] = array[i + halfLength];
    }
    return ret;
}

public static void main(String[] a) {
    Integer[] bar = { 1, 2, 3, 4, 5 };
    Integer[][] dims = toTwoDim(bar);
    for (Integer[] r : dims) {
        for (Integer d : r) {
            System.out.print(d + " ");
        }
        System.out.println();
    }
}

输出:
1 2
3 4 5

'toTwoDim'函数的泛型类型被擦除,但传入数组的元素类型可以通过反射获得!

答案 3 :(得分:0)

你可以这样做,这不需要抑制任何警告。

public static <T> T[][] toTwoDim(Class<T[][]> clazz, T[] array)  
{  
   int halfLength = array.length / 2;  
   T[][] ret = clazz.cast(Array.newInstance(clazz.getComponentType().getComponentType(), 2, halfLength + 1));  
   System.arraycopy(array, 0, ret[0], 0, halfLength);  
   System.arraycopy(array, halfLength, ret[1], 0, array.length - halfLength);  
   return ret;  
}