与通用阵列的ArrayList铸造ArrayList.toArray() [英] casting ArrayList.toArray() with ArrayList of Generic Arrays

查看:117
本文介绍了与通用阵列的ArrayList铸造ArrayList.toArray()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个棘手的问题,我很接近放弃了所有的希望。我试图做一个
功能,但我有问题越来越 ArrayList.toArray()返回我想要的类型。

A difficult question which I'm close to giving up all hope on. I'm trying to make a function, but am having problems getting ArrayList.toArray() to return the type I want.

下面是一个演示我的问题小例子:

Here's the minimal example that demonstrates my problem:

public static <T> T[] test(T one, T two) {
    java.util.List<T> list = new ArrayList<T>();
    list.add(one);
    list.add(two);
    return (T[]) list.toArray();
}

一般情况下我可以使用的形式(T [])list.toArray(新T [0])但是有两个困难增加:


  1. 因为协方差规则,我不能强制转换数组,(T [])myObjectArray 给出了一个 ClassCastException异常

  2. 您不能创建泛型类型的新实例,这意味着我不能例如新T [] 。我也可以使用 ArrayList的元素之一克隆或设法得到它的类。

  1. Because of the covariance rules I cannot typecast arrays, (T[]) myObjectArray gives a ClassCastException
  2. You cannot create a new instance of a generic type, meaning I cannot instance new T[]. Nor can I use clone on one of the elements of ArrayList or try to get its class.

我一直在尝试使用以下调用来获得一些信息:

I've been trying to get some information using the following call:

public static void main(String[] args) {
   System.out.println(test("onestring", "twostrings"));
}

结果是形式 [Ljava.lang.Object的; @ 3e25a5 这表明在返回类型转换无效。奇怪的是以下内容:

the result is of the form [Ljava.lang.Object;@3e25a5 suggesting that the typecast on the return is not effective. strangely the following:

public static void main(String[] args) {
    System.out.println(test("onestring", "twostrings").getClass());
}

回来了:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at patchLinker.Utilities.main(Utilities.java:286)

所以我最好的猜测是,它认为是它是一个字符串数组标签明智的,但内部是一个对象数组,并访问任何企图使该inconsistancy出来。

So my best guess is that it think's it's a String array label wise, but internally is an Object array, and any attempts to access brings that inconsistancy out.

如果任何人都可以找到解决此工作的任何方式(因为两个正常的解决方法被剥夺了我)我会非常感激。

If anyone can find any way of working around this (since the two normal workarounds are denied to me) I'd be very greatful.

K.Barad
JDK1.6

K.Barad JDK1.6

修改

感谢Peter Lawrey解决最初的问题。现在的问题是,如何使解决方案适用于我不太简单的例子:

Thanks to Peter Lawrey for solving the initial problem. Now the issue is how to make the solution apply to my less trivial example:

public static <T> T[] unTreeArray(T[][] input) {
    java.util.List<T> outList = new ArrayList<T>();
    java.util.List<T> tempList;
    T[] typeVar;
    for (T[] subArray : input) {
        tempList = java.util.Arrays.asList(subArray);
        outList.addAll(tempList);
    }
    if (input.length > 0) {
        typeVar = input[0];
    } else {
        return null;
    }
    return (T[]) outList.toArray((T[]) java.lang.reflect.Array.newInstance(typeVar.getClass(),outList.size()));
}

public static void main(String[] args) {
    String[][] lines = { { "111", "122", "133" }, { "211", "222", "233" } };
    unTreeArray(lines);
}

目前的结果是

Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at java.util.ArrayList.toArray(Unknown Source)
at patchLinker.Utilities.unTreeArray(Utilities.java:159)
at patchLinker.Utilities.main(Utilities.java:301)

我仍然在做一些测试,看看我是否能得到任何比这更多的有用信息,但此刻我不知道从哪里开始。我得到它,我会添加更多的信息,我得到的。

I'm still doing some tests to see if I can get any more useful information than this, but at the moment I'm not sure where to start. I'll add any more information I get as I get it.

K.Barad

编辑2

现在的一些详细信息。我试图手动构建阵列和的elementwise转移的项目,所以我会类型转换为T,而不是T []。我发现一个有趣的结果:

Some more information now. I've tried to build the array manually and transfer the items in elementwise, so I'd be typecasting as T, rather than T[]. I found an interesting result:

public static <T> T[] unTreeArray(T[][] input) {
    java.util.List<T> outList = new ArrayList<T>();
    java.util.List<T> tempList;
    T[] outArray;
    for (T[] subArray : input) {
        tempList = java.util.Arrays.asList(subArray);
        outList.addAll(tempList);
    }
    if (outList.size() == 0) {
        return null;
    } else {
        outArray = input[0];// use as a class sampler
        outArray =
                (T[]) java.lang.reflect.Array.newInstance(outArray.getClass(), outList.size());
        for (int i = 0; i < outList.size(); i++) {
            System.out.println(i + "  " + outArray.length + "   " + outList.size() + "   "  + outList.get(i));
            outArray[i] = (T) outList.get(i);
        }
        System.out.println(outArray.length);
        return outArray;
    }
}

我仍然得到以下输出:

I still get the following output:

0  6   6   111
Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
at patchLinker.Utilities.unTreeArray(Utilities.java:291)
at patchLinker.Utilities.main(Utilities.java:307)

这是否意味着你不能写入 T []即使你设法间接创建一个

推荐答案

这是你的第二个code样品的问题,因为引起你的 T [] typeVar :输入是一个两维数组,所以输入[0] 将返回一维数组(一个String [],而不是一个字符串,如预期)。

The problem on your second code sample is caused because of your T[] typeVar: Input is a two dim array, so input[0] will return a one dim array (a String[], instead a String, as expected).

如果你要转换您的列表&LT; T&GT; T [] ,你需要一个 T typeVar

If your are to convert your List<T> to a T[], you'll need a T typeVar,

要解决这个问题:

public static <T> T[] unTreeArray(T[][] input) {
    java.util.List<T> outList = new ArrayList<T>();
    java.util.List<T> tempList;

    if (input.length == 0) {
        return null;
    }


    T typeVar=null;
    for (T[] subArray : input) {
        if(typeVar==null && subArray.length>0) {
            typeVar=subArray[0];
        }
        tempList = java.util.Arrays.asList(subArray);
        outList.addAll(tempList);
    }

    return outList.toArray((T[]) Array.newInstance(typeVar.getClass(),0));
}

public static void main(String[] args) {
    String[][] lines = { { "111", "122", "133" }, { "211", "222", "233" } };
    String[] result=unTreeArray(lines);

    System.out.println(result);

    System.out.println(result.getClass());

        //added for completion:
    System.out.println( Arrays.toString(result));

}

输出结果:

[Ljava.lang.String; @ 5a405a4类结果
  [Ljava.lang.String;结果
  [111,122,133,211,222,233]

[Ljava.lang.String;@5a405a4 class
[Ljava.lang.String;
[111, 122, 133, 211, 222, 233]

这篇关于与通用阵列的ArrayList铸造ArrayList.toArray()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆