Note that there are some explanatory texts on larger screens.

plurals
  1. POcasting ArrayList.toArray() with ArrayList of Generic Arrays
    primarykey
    data
    text
    <p>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 <code>ArrayList.toArray()</code> to return the type I want. </p> <p>Here's the minimal example that demonstrates my problem:</p> <pre><code>public static &lt;T&gt; T[] test(T one, T two) { java.util.List&lt;T&gt; list = new ArrayList&lt;T&gt;(); list.add(one); list.add(two); return (T[]) list.toArray(); } </code></pre> <p>Normally I'd be able to use the form <code>(T[]) list.toArray(new T[0])</code> but there are two added difficulties: </p> <ol> <li>Because of the covariance rules I cannot typecast arrays, <code>(T[]) myObjectArray</code> gives a <code>ClassCastException</code></li> <li>You cannot create a new instance of a generic type, meaning I cannot instance <code>new T[]</code>. Nor can I use clone on one of the elements of <code>ArrayList</code> or try to get its class.</li> </ol> <p>I've been trying to get some information using the following call:</p> <pre><code>public static void main(String[] args) { System.out.println(test("onestring", "twostrings")); } </code></pre> <p>the result is of the form <code>[Ljava.lang.Object;@3e25a5</code> suggesting that the typecast on the return is not effective. strangely the following:</p> <pre><code>public static void main(String[] args) { System.out.println(test("onestring", "twostrings").getClass()); } </code></pre> <p>comes back with: </p> <pre><code>Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; at patchLinker.Utilities.main(Utilities.java:286) </code></pre> <p>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. </p> <p>If anyone can find any way of working around this (since the two normal workarounds are denied to me) I'd be very greatful. </p> <p>K.Barad JDK1.6</p> <hr> <p>Edit</p> <hr> <p>Thanks to Peter Lawrey for solving the initial problem. Now the issue is how to make the solution apply to my less trivial example:</p> <pre><code>public static &lt;T&gt; T[] unTreeArray(T[][] input) { java.util.List&lt;T&gt; outList = new ArrayList&lt;T&gt;(); java.util.List&lt;T&gt; tempList; T[] typeVar; for (T[] subArray : input) { tempList = java.util.Arrays.asList(subArray); outList.addAll(tempList); } if (input.length &gt; 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); } </code></pre> <p>The result at the moment is</p> <pre><code>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) </code></pre> <p>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.</p> <p>K.Barad</p> <hr> <p>edit 2</p> <hr> <p>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:</p> <pre><code>public static &lt;T&gt; T[] unTreeArray(T[][] input) { java.util.List&lt;T&gt; outList = new ArrayList&lt;T&gt;(); java.util.List&lt;T&gt; 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 &lt; 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; } } </code></pre> <p>I still get the following output:</p> <pre><code>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) </code></pre> <p>Does this mean you can't write to a <code>T[]</code> even if you manage to create one indirectly? </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload