11/*
2- * Copyright 2002-2013 the original author or authors.
2+ * Copyright 2002-2014 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1818
1919import java .util .ArrayList ;
2020import java .util .Collection ;
21+ import java .util .EnumMap ;
22+ import java .util .EnumSet ;
2123import java .util .HashMap ;
2224import java .util .HashSet ;
2325import java .util .LinkedHashMap ;
3335import java .util .TreeMap ;
3436import java .util .TreeSet ;
3537
38+ import org .springframework .util .Assert ;
3639import org .springframework .util .LinkedMultiValueMap ;
3740import org .springframework .util .MultiValueMap ;
3841
@@ -72,9 +75,11 @@ public abstract class CollectionFactory {
7275 approximableCollectionTypes .add (HashSet .class );
7376 approximableCollectionTypes .add (LinkedHashSet .class );
7477 approximableCollectionTypes .add (TreeSet .class );
78+ approximableCollectionTypes .add (EnumSet .class );
7579 approximableMapTypes .add (HashMap .class );
7680 approximableMapTypes .add (LinkedHashMap .class );
7781 approximableMapTypes .add (TreeMap .class );
82+ approximableMapTypes .add (EnumMap .class );
7883 }
7984
8085
@@ -91,68 +96,87 @@ public static boolean isApproximableCollectionType(Class<?> collectionType) {
9196
9297 /**
9398 * Create the most approximate collection for the given collection.
94- * <p>Creates an ArrayList, TreeSet or linked Set for a List, SortedSet
95- * or Set, respectively.
9699 * @param collection the original Collection object
97- * @param initialCapacity the initial capacity
100+ * @param capacity the initial capacity
98101 * @return the new Collection instance
99- * @see java.util.ArrayList
100- * @see java.util.TreeSet
101102 * @see java.util.LinkedHashSet
103+ * @see java.util.TreeSet
104+ * @see java.util.EnumSet
105+ * @see java.util.ArrayList
106+ * @see java.util.LinkedList
102107 */
103108 @ SuppressWarnings ("unchecked" )
104- public static <E > Collection <E > createApproximateCollection (Object collection , int initialCapacity ) {
109+ public static <E > Collection <E > createApproximateCollection (Object collection , int capacity ) {
105110 if (collection instanceof LinkedList ) {
106111 return new LinkedList <E >();
107112 }
108113 else if (collection instanceof List ) {
109- return new ArrayList <E >(initialCapacity );
114+ return new ArrayList <E >(capacity );
115+ }
116+ else if (collection instanceof EnumSet ) {
117+ return EnumSet .copyOf ((Collection ) collection );
110118 }
111119 else if (collection instanceof SortedSet ) {
112120 return new TreeSet <E >(((SortedSet <E >) collection ).comparator ());
113121 }
114122 else {
115- return new LinkedHashSet <E >(initialCapacity );
123+ return new LinkedHashSet <E >(capacity );
116124 }
117125 }
118126
119127 /**
120128 * Create the most appropriate collection for the given collection type.
121- * <p>Creates an ArrayList, TreeSet or linked Set for a List, SortedSet
122- * or Set, respectively.
123- * @param collectionType the desired type of the target Collection
124- * @param initialCapacity the initial capacity
129+ * <p>Delegates to {@link #createCollection(Class, Class, int)} with a
130+ * {@code null} element type.
131+ * @param collectionClass the desired type of the target Collection
132+ * @param capacity the initial capacity
133+ * @return the new Collection instance
134+ */
135+ public static <E > Collection <E > createCollection (Class <?> collectionClass , int capacity ) {
136+ return createCollection (collectionClass , null , capacity );
137+ }
138+
139+ /**
140+ * Create the most appropriate collection for the given collection type.
141+ * @param collectionClass the desired type of the target Collection
142+ * @param elementType the collection's element type, or {@code null} if not known
143+ * @param capacity the initial capacity
125144 * @return the new Collection instance
126- * @see java.util.ArrayList
127- * @see java.util.TreeSet
128145 * @see java.util.LinkedHashSet
146+ * @see java.util.TreeSet
147+ * @see java.util.EnumSet
148+ * @see java.util.ArrayList
129149 */
130150 @ SuppressWarnings ("unchecked" )
131- public static <E > Collection <E > createCollection (Class <?> collectionType , int initialCapacity ) {
132- if (collectionType .isInterface ()) {
133- if (List .class .equals (collectionType )) {
134- return new ArrayList <E >(initialCapacity );
151+ public static <E > Collection <E > createCollection (Class <?> collectionClass , Class <?> elementType , int capacity ) {
152+ if (collectionClass .isInterface ()) {
153+ if (Set .class .equals (collectionClass ) || Collection . class . equals ( collectionClass )) {
154+ return new LinkedHashSet <E >(capacity );
135155 }
136- else if (SortedSet .class .equals (collectionType ) || NavigableSet . class . equals ( collectionType )) {
137- return new TreeSet <E >();
156+ else if (List .class .equals (collectionClass )) {
157+ return new ArrayList <E >(capacity );
138158 }
139- else if (Set .class .equals (collectionType ) || Collection .class .equals (collectionType )) {
140- return new LinkedHashSet <E >(initialCapacity );
159+ else if (SortedSet .class .equals (collectionClass ) || NavigableSet .class .equals (collectionClass )) {
160+ return new TreeSet <E >();
141161 }
142162 else {
143- throw new IllegalArgumentException ("Unsupported Collection interface: " + collectionType .getName ());
163+ throw new IllegalArgumentException ("Unsupported Collection interface: " + collectionClass .getName ());
144164 }
145165 }
166+ else if (EnumSet .class .equals (collectionClass )) {
167+ Assert .notNull (elementType , "Cannot create EnumSet for unknown element type" );
168+ return EnumSet .noneOf ((Class ) elementType );
169+ }
146170 else {
147- if (!Collection .class .isAssignableFrom (collectionType )) {
148- throw new IllegalArgumentException ("Unsupported Collection type: " + collectionType .getName ());
171+ if (!Collection .class .isAssignableFrom (collectionClass )) {
172+ throw new IllegalArgumentException ("Unsupported Collection type: " + collectionClass .getName ());
149173 }
150174 try {
151- return (Collection <E >) collectionType .newInstance ();
175+ return (Collection <E >) collectionClass .newInstance ();
152176 }
153177 catch (Exception ex ) {
154- throw new IllegalArgumentException ("Could not instantiate Collection type: " +
155- collectionType .getName (), ex );
178+ throw new IllegalArgumentException (
179+ "Could not instantiate Collection type: " + collectionClass .getName (), ex );
156180 }
157181 }
158182 }
@@ -170,58 +194,78 @@ public static boolean isApproximableMapType(Class<?> mapType) {
170194
171195 /**
172196 * Create the most approximate map for the given map.
173- * <p>Creates a TreeMap or linked Map for a SortedMap or Map, respectively.
174197 * @param map the original Map object
175- * @param initialCapacity the initial capacity
198+ * @param capacity the initial capacity
176199 * @return the new Map instance
177200 * @see java.util.TreeMap
178201 * @see java.util.LinkedHashMap
179202 */
180- @ SuppressWarnings ("unchecked" )
181- public static <K , V > Map <K , V > createApproximateMap (Object map , int initialCapacity ) {
182- if (map instanceof SortedMap ) {
203+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
204+ public static <K , V > Map <K , V > createApproximateMap (Object map , int capacity ) {
205+ if (map instanceof EnumMap ) {
206+ return new EnumMap ((Map ) map );
207+ }
208+ else if (map instanceof SortedMap ) {
183209 return new TreeMap <K , V >(((SortedMap <K , V >) map ).comparator ());
184210 }
185211 else {
186- return new LinkedHashMap <K , V >(initialCapacity );
212+ return new LinkedHashMap <K , V >(capacity );
187213 }
188214 }
189215
190216 /**
191217 * Create the most approximate map for the given map.
192- * <p>Creates a TreeMap or linked Map for a SortedMap or Map, respectively.
193- * @param mapType the desired type of the target Map
194- * @param initialCapacity the initial capacity
218+ * <p>Delegates to {@link #createMap(Class, Class, int)} with a
219+ * {@code null} key type.
220+ * @param mapClass the desired type of the target Map
221+ * @param capacity the initial capacity
222+ * @return the new Map instance
223+ */
224+ public static <K , V > Map <K , V > createMap (Class <?> mapClass , int capacity ) {
225+ return createMap (mapClass , null , capacity );
226+ }
227+
228+ /**
229+ * Create the most approximate map for the given map.
230+ * @param mapClass the desired type of the target Map
231+ * @param keyType the map's key type, or {@code null} if not known
232+ * @param capacity the initial capacity
195233 * @return the new Map instance
196- * @see java.util.TreeMap
197234 * @see java.util.LinkedHashMap
235+ * @see java.util.TreeMap
236+ * @see java.util.EnumMap
237+ * @see org.springframework.util.LinkedMultiValueMap
198238 */
199- @ SuppressWarnings ({ "unchecked" , "rawtypes" })
200- public static <K , V > Map <K , V > createMap (Class <?> mapType , int initialCapacity ) {
201- if (mapType .isInterface ()) {
202- if (Map .class .equals (mapType )) {
203- return new LinkedHashMap <K , V >(initialCapacity );
239+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
240+ public static <K , V > Map <K , V > createMap (Class <?> mapClass , Class <?> keyType , int capacity ) {
241+ if (mapClass .isInterface ()) {
242+ if (Map .class .equals (mapClass )) {
243+ return new LinkedHashMap <K , V >(capacity );
204244 }
205- else if (SortedMap .class .equals (mapType ) || NavigableMap .class .equals (mapType )) {
245+ else if (SortedMap .class .equals (mapClass ) || NavigableMap .class .equals (mapClass )) {
206246 return new TreeMap <K , V >();
207247 }
208- else if (MultiValueMap .class .equals (mapType )) {
248+ else if (MultiValueMap .class .equals (mapClass )) {
209249 return new LinkedMultiValueMap ();
210250 }
211251 else {
212- throw new IllegalArgumentException ("Unsupported Map interface: " + mapType .getName ());
252+ throw new IllegalArgumentException ("Unsupported Map interface: " + mapClass .getName ());
213253 }
214254 }
255+ else if (EnumMap .class .equals (mapClass )) {
256+ Assert .notNull (keyType , "Cannot create EnumMap for unknown key type" );
257+ return new EnumMap (keyType );
258+ }
215259 else {
216- if (!Map .class .isAssignableFrom (mapType )) {
217- throw new IllegalArgumentException ("Unsupported Map type: " + mapType .getName ());
260+ if (!Map .class .isAssignableFrom (mapClass )) {
261+ throw new IllegalArgumentException ("Unsupported Map type: " + mapClass .getName ());
218262 }
219263 try {
220- return (Map <K , V >) mapType .newInstance ();
264+ return (Map <K , V >) mapClass .newInstance ();
221265 }
222266 catch (Exception ex ) {
223- throw new IllegalArgumentException ("Could not instantiate Map type: " +
224- mapType .getName (), ex );
267+ throw new IllegalArgumentException (
268+ "Could not instantiate Map type: " + mapClass .getName (), ex );
225269 }
226270 }
227271 }
0 commit comments