K.B*_*rad 9 java arrays generics casting arraylist
一个困难的问题,我接近放弃所有的希望.我正在尝试创建一个函数,但是在ArrayList.toArray()
返回我想要的类型时遇到了问题.
这是演示我的问题的最小例子:
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();
}
Run Code Online (Sandbox Code Playgroud)
通常我可以使用表单,(T[]) list.toArray(new T[0])
但有两个额外的困难:
(T[]) myObjectArray
给出一个ClassCastException
new T[]
.我也不能在其中一个元素上使用克隆ArrayList
或尝试获得它的类.我一直在尝试使用以下调用获取一些信息:
public static void main(String[] args) {
System.out.println(test("onestring", "twostrings"));
}
Run Code Online (Sandbox Code Playgroud)
结果[Ljava.lang.Object;@3e25a5
表明返回的类型转换无效.奇怪的是以下几点:
public static void main(String[] args) {
System.out.println(test("onestring", "twostrings").getClass());
}
Run Code Online (Sandbox Code Playgroud)
回来:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at patchLinker.Utilities.main(Utilities.java:286)
Run Code Online (Sandbox Code Playgroud)
所以我最好的猜测是它认为它是一个明智的String数组标签,但内部是一个Object数组,任何访问尝试都会带来不一致性.
如果有人能找到解决这个问题的方法(因为我拒绝了两个正常的解决方法),我会非常感激.
K.Barad JDK1.6
编辑
感谢Peter Lawrey解决最初的问题.现在的问题是如何使解决方案适用于我不太重要的例子:
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);
}
Run Code Online (Sandbox Code Playgroud)
目前的结果是
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)
Run Code Online (Sandbox Code Playgroud)
我还在做一些测试,看看我是否能获得比这更有用的信息,但目前我还不知道从哪里开始.我会在收到的时候添加更多信息.
K.Barad
编辑2
现在有更多信息.我试图手动构建数组并以元素方式传输项目,因此我将类型转换为T,而不是T [].我发现了一个有趣的结果:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我仍然得到以下输出:
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)
Run Code Online (Sandbox Code Playgroud)
这是否意味着T[]
即使您设法间接创建一个,也无法写入?
第二个代码示例的问题是由于您的T[] typeVar
:输入是一个二维数组,因此input[0]
将返回一个一维数组(一个 String[],而不是一个 String,如预期的那样)。
如果您要将您的转换List<T>
为 a T[]
,您将需要一个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));
}
Run Code Online (Sandbox Code Playgroud)
结果输出:
[Ljava.lang.String;@5a405a4 类
[Ljava.lang.String;
[111、122、133、211、222、233]