JDK-6310858 : (coll) EnumMap.entrySet().toArray(T[] a) is incorrectly implemented
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-08-15
  • Updated: 2012-10-08
  • Resolved: 2005-09-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u6Fixed 6 b51Fixed
Related Reports
Relates :  
Relates :  
Description
EnumMap.entrySet.toArray(T[]) always returns a freshly allocated array,
even when all of its elements fit into the argument array.

Comments
SUGGESTED FIX --- /u/martin/ws/mustang/src/share/classes/java/util/EnumMap.java 2004-08-27 15:54:48.955912000 -0700 +++ /u/martin/ws/toArray/src/share/classes/java/util/EnumMap.java 2005-08-14 20:02:02.746115000 -0700 @@ -40,7 +40,8 @@ * unsynchronized access: * * <pre> - * Map&lt;EnumKey, V&gt; m = Collections.synchronizedMap(new EnumMap(...)); + * Map&lt;EnumKey, V&gt; m + * = Collections.synchronizedMap(new EnumMap&lt;EnumKey, V&gt;(...)); * </pre> * * <p>Implementation note: All basic operations execute in constant time. @@ -458,10 +459,15 @@ public Object[] toArray() { return fillEntryArray(new Object[size]); } + @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { - Object[] result = (Object[]) java.lang.reflect.Array.newInstance( - a.getClass().getComponentType(), size); - return (T[]) fillEntryArray(result); + int size = size(); + if (a.length < size) + a = (T[])java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), size); + if (a.length > size) + a[size] = null; + return (T[]) fillEntryArray(a); } private Object[] fillEntryArray(Object[] a) { int j = 0; --- /u/martin/ws/mustang/test/java/util/EnumMap/ToArray.java 1969-12-31 16:00:00.000000000 -0800 +++ /u/martin/ws/toArray/test/java/util/EnumMap/ToArray.java 2005-08-14 20:49:02.556010000 -0700 @@ -0,0 +1,44 @@ +/* + * @test 1.1 05/08/14 + * @bug 6310858 + * @summary Tests for toArray + * @author Martin Buchholz + */ + +import java.util.*; + +public class ToArray { + enum Country { FRENCH, POLISH } + public static void main(String[] args) throws Throwable { + Map<Country, String> m = new EnumMap<Country, String>(Country.class); + m.put(Country.FRENCH, "connection"); + m.put(Country.POLISH, "sausage"); + + Object[] z = m.entrySet().toArray(); + System.out.println(Arrays.toString(z)); + if (! (z.getClass() == Object[].class && + z.length == 2 && + ((Map.Entry)z[0]).getKey() == Country.FRENCH && + ((Map.Entry)z[1]).getKey() == Country.POLISH)) + throw new AssertionError(); + + Map.Entry[] x1 = new Map.Entry[3]; + x1[2] = m.entrySet().iterator().next(); + Map.Entry[] x2 = m.entrySet().toArray(x1); + System.out.println(Arrays.toString(x2)); + if (! (x1 == x2 && + x2[0].getKey() == Country.FRENCH && + x2[1].getKey() == Country.POLISH && + x2[2] == null)) + throw new AssertionError(); + + Map.Entry[] y1 = new Map.Entry[1]; + Map.Entry[] y2 = m.entrySet().toArray(y1); + System.out.println(Arrays.toString(y2)); + if (! (y1 != y2 && + y2.length == 2 && + y2[0].getKey() == Country.FRENCH && + y2[1].getKey() == Country.POLISH)) + throw new AssertionError(); + } +}
15-08-2005

EVALUATION Yes.
15-08-2005