KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > CollectionUtils


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.collections;
17
18 import java.lang.reflect.Array JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Enumeration JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ListIterator JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Set JavaDoc;
29
30 import org.apache.commons.collections.collection.PredicatedCollection;
31 import org.apache.commons.collections.collection.SynchronizedCollection;
32 import org.apache.commons.collections.collection.TransformedCollection;
33 import org.apache.commons.collections.collection.TypedCollection;
34 import org.apache.commons.collections.collection.UnmodifiableBoundedCollection;
35 import org.apache.commons.collections.collection.UnmodifiableCollection;
36
37 /**
38  * Provides utility methods and decorators for {@link Collection} instances.
39  *
40  * @since Commons Collections 1.0
41  * @version $Revision: 1.61 $ $Date: 2004/04/27 20:00:18 $
42  *
43  * @author Rodney Waldhoff
44  * @author Paul Jack
45  * @author Stephen Colebourne
46  * @author Steve Downey
47  * @author Herve Quiroz
48  * @author Peter KoBek
49  * @author Matthew Hawthorne
50  * @author Janek Bogucki
51  * @author Phil Steitz
52  * @author Steven Melzer
53  * @author Jon Schewe
54  */

55 public class CollectionUtils {
56
57     /** Constant to avoid repeated object creation */
58     private static Integer JavaDoc INTEGER_ONE = new Integer JavaDoc(1);
59
60     /**
61      * An empty unmodifiable collection.
62      * The JDK provides empty Set and List implementations which could be used for
63      * this purpose. However they could be cast to Set or List which might be
64      * undesirable. This implementation only implements Collection.
65      */

66     public static final Collection JavaDoc EMPTY_COLLECTION = UnmodifiableCollection.decorate(new ArrayList JavaDoc());
67
68     /**
69      * <code>CollectionUtils</code> should not normally be instantiated.
70      */

71     public CollectionUtils() {
72     }
73
74     /**
75      * Returns a {@link Collection} containing the union
76      * of the given {@link Collection}s.
77      * <p>
78      * The cardinality of each element in the returned {@link Collection}
79      * will be equal to the maximum of the cardinality of that element
80      * in the two given {@link Collection}s.
81      *
82      * @param a the first collection, must not be null
83      * @param b the second collection, must not be null
84      * @return the union of the two collections
85      * @see Collection#addAll
86      */

87     public static Collection JavaDoc union(final Collection JavaDoc a, final Collection JavaDoc b) {
88         ArrayList JavaDoc list = new ArrayList JavaDoc();
89         Map JavaDoc mapa = getCardinalityMap(a);
90         Map JavaDoc mapb = getCardinalityMap(b);
91         Set JavaDoc elts = new HashSet JavaDoc(a);
92         elts.addAll(b);
93         Iterator JavaDoc it = elts.iterator();
94         while(it.hasNext()) {
95             Object JavaDoc obj = it.next();
96             for(int i=0,m=Math.max(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) {
97                 list.add(obj);
98             }
99         }
100         return list;
101     }
102
103     /**
104      * Returns a {@link Collection} containing the intersection
105      * of the given {@link Collection}s.
106      * <p>
107      * The cardinality of each element in the returned {@link Collection}
108      * will be equal to the minimum of the cardinality of that element
109      * in the two given {@link Collection}s.
110      *
111      * @param a the first collection, must not be null
112      * @param b the second collection, must not be null
113      * @return the intersection of the two collections
114      * @see Collection#retainAll
115      * @see #containsAny
116      */

117     public static Collection JavaDoc intersection(final Collection JavaDoc a, final Collection JavaDoc b) {
118         ArrayList JavaDoc list = new ArrayList JavaDoc();
119         Map JavaDoc mapa = getCardinalityMap(a);
120         Map JavaDoc mapb = getCardinalityMap(b);
121         Set JavaDoc elts = new HashSet JavaDoc(a);
122         elts.addAll(b);
123         Iterator JavaDoc it = elts.iterator();
124         while(it.hasNext()) {
125             Object JavaDoc obj = it.next();
126             for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) {
127                 list.add(obj);
128             }
129         }
130         return list;
131     }
132
133     /**
134      * Returns a {@link Collection} containing the exclusive disjunction
135      * (symmetric difference) of the given {@link Collection}s.
136      * <p>
137      * The cardinality of each element <i>e</i> in the returned {@link Collection}
138      * will be equal to
139      * <tt>max(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>)) - min(cardinality(<i>e</i>,<i>a</i>),cardinality(<i>e</i>,<i>b</i>))</tt>.
140      * <p>
141      * This is equivalent to
142      * <tt>{@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})</tt>
143      * or
144      * <tt>{@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})</tt>.
145      *
146      * @param a the first collection, must not be null
147      * @param b the second collection, must not be null
148      * @return the symmetric difference of the two collections
149      */

150     public static Collection JavaDoc disjunction(final Collection JavaDoc a, final Collection JavaDoc b) {
151         ArrayList JavaDoc list = new ArrayList JavaDoc();
152         Map JavaDoc mapa = getCardinalityMap(a);
153         Map JavaDoc mapb = getCardinalityMap(b);
154         Set JavaDoc elts = new HashSet JavaDoc(a);
155         elts.addAll(b);
156         Iterator JavaDoc it = elts.iterator();
157         while(it.hasNext()) {
158             Object JavaDoc obj = it.next();
159             for(int i=0,m=((Math.max(getFreq(obj,mapa),getFreq(obj,mapb)))-(Math.min(getFreq(obj,mapa),getFreq(obj,mapb))));i<m;i++) {
160                 list.add(obj);
161             }
162         }
163         return list;
164     }
165
166     /**
167      * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>.
168      * The cardinality of each element <i>e</i> in the returned {@link Collection}
169      * will be the cardinality of <i>e</i> in <i>a</i> minus the cardinality
170      * of <i>e</i> in <i>b</i>, or zero, whichever is greater.
171      *
172      * @param a the collection to subtract from, must not be null
173      * @param b the collection to subtract, must not be null
174      * @return a new collection with the results
175      * @see Collection#removeAll
176      */

177     public static Collection JavaDoc subtract(final Collection JavaDoc a, final Collection JavaDoc b) {
178         ArrayList JavaDoc list = new ArrayList JavaDoc( a );
179         for (Iterator JavaDoc it = b.iterator(); it.hasNext();) {
180             list.remove(it.next());
181         }
182         return list;
183     }
184
185     /**
186      * Returns <code>true</code> iff at least one element is in both collections.
187      * <p>
188      * In other words, this method returns <code>true</code> iff the
189      * {@link #intersection} of <i>coll1</i> and <i>coll2</i> is not empty.
190      *
191      * @param coll1 the first collection, must not be null
192      * @param coll2 the first collection, must not be null
193      * @return <code>true</code> iff the intersection of the collections is non-empty
194      * @since 2.1
195      * @see #intersection
196      */

197     public static boolean containsAny(final Collection JavaDoc coll1, final Collection JavaDoc coll2) {
198         if (coll1.size() < coll2.size()) {
199             for (Iterator JavaDoc it = coll1.iterator(); it.hasNext();) {
200                 if (coll2.contains(it.next())) {
201                     return true;
202                 }
203             }
204         } else {
205             for (Iterator JavaDoc it = coll2.iterator(); it.hasNext();) {
206                 if (coll1.contains(it.next())) {
207                     return true;
208                 }
209             }
210         }
211         return false;
212     }
213
214     /**
215      * Returns a {@link Map} mapping each unique element in the given
216      * {@link Collection} to an {@link Integer} representing the number
217      * of occurrences of that element in the {@link Collection}.
218      * <p>
219      * Only those elements present in the collection will appear as
220      * keys in the map.
221      *
222      * @param coll the collection to get the cardinality map for, must not be null
223      * @return the populated cardinality map
224      */

225     public static Map JavaDoc getCardinalityMap(final Collection JavaDoc coll) {
226         Map JavaDoc count = new HashMap JavaDoc();
227         for (Iterator JavaDoc it = coll.iterator(); it.hasNext();) {
228             Object JavaDoc obj = it.next();
229             Integer JavaDoc c = (Integer JavaDoc) (count.get(obj));
230             if (c == null) {
231                 count.put(obj,INTEGER_ONE);
232             } else {
233                 count.put(obj,new Integer JavaDoc(c.intValue() + 1));
234             }
235         }
236         return count;
237     }
238
239     /**
240      * Returns <tt>true</tt> iff <i>a</i> is a sub-collection of <i>b</i>,
241      * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
242      * than or equal to the cardinality of <i>e</i> in <i>b</i>,
243      * for each element <i>e</i> in <i>a</i>.
244      *
245      * @param a the first (sub?) collection, must not be null
246      * @param b the second (super?) collection, must not be null
247      * @return <code>true</code> iff <i>a</i> is a sub-collection of <i>b</i>
248      * @see #isProperSubCollection
249      * @see Collection#containsAll
250      */

251     public static boolean isSubCollection(final Collection JavaDoc a, final Collection JavaDoc b) {
252         Map JavaDoc mapa = getCardinalityMap(a);
253         Map JavaDoc mapb = getCardinalityMap(b);
254         Iterator JavaDoc it = a.iterator();
255         while (it.hasNext()) {
256             Object JavaDoc obj = it.next();
257             if (getFreq(obj, mapa) > getFreq(obj, mapb)) {
258                 return false;
259             }
260         }
261         return true;
262     }
263
264     /**
265      * Returns <tt>true</tt> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>,
266      * that is, iff the cardinality of <i>e</i> in <i>a</i> is less
267      * than or equal to the cardinality of <i>e</i> in <i>b</i>,
268      * for each element <i>e</i> in <i>a</i>, and there is at least one
269      * element <i>f</i> such that the cardinality of <i>f</i> in <i>b</i>
270      * is strictly greater than the cardinality of <i>f</i> in <i>a</i>.
271      * <p>
272      * The implementation assumes
273      * <ul>
274      * <li><code>a.size()</code> and <code>b.size()</code> represent the
275      * total cardinality of <i>a</i> and <i>b</i>, resp. </li>
276      * <li><code>a.size() < Integer.MAXVALUE</code></li>
277      * </ul>
278      *
279      * @param a the first (sub?) collection, must not be null
280      * @param b the second (super?) collection, must not be null
281      * @return <code>true</code> iff <i>a</i> is a <i>proper</i> sub-collection of <i>b</i>
282      * @see #isSubCollection
283      * @see Collection#containsAll
284      */

285     public static boolean isProperSubCollection(final Collection JavaDoc a, final Collection JavaDoc b) {
286         return (a.size() < b.size()) && CollectionUtils.isSubCollection(a,b);
287     }
288
289     /**
290      * Returns <tt>true</tt> iff the given {@link Collection}s contain
291      * exactly the same elements with exactly the same cardinalities.
292      * <p>
293      * That is, iff the cardinality of <i>e</i> in <i>a</i> is
294      * equal to the cardinality of <i>e</i> in <i>b</i>,
295      * for each element <i>e</i> in <i>a</i> or <i>b</i>.
296      *
297      * @param a the first collection, must not be null
298      * @param b the second collection, must not be null
299      * @return <code>true</code> iff the collections contain the same elements with the same cardinalities.
300      */

301     public static boolean isEqualCollection(final Collection JavaDoc a, final Collection JavaDoc b) {
302         if(a.size() != b.size()) {
303             return false;
304         } else {
305             Map JavaDoc mapa = getCardinalityMap(a);
306             Map JavaDoc mapb = getCardinalityMap(b);
307             if(mapa.size() != mapb.size()) {
308                 return false;
309             } else {
310                 Iterator JavaDoc it = mapa.keySet().iterator();
311                 while(it.hasNext()) {
312                     Object JavaDoc obj = it.next();
313                     if(getFreq(obj,mapa) != getFreq(obj,mapb)) {
314                         return false;
315                     }
316                 }
317                 return true;
318             }
319         }
320     }
321
322     /**
323      * Returns the number of occurrences of <i>obj</i> in <i>coll</i>.
324      *
325      * @param obj the object to find the cardinality of
326      * @param coll the collection to search
327      * @return the the number of occurrences of obj in coll
328      */

329     public static int cardinality(Object JavaDoc obj, final Collection JavaDoc coll) {
330         if (coll instanceof Set JavaDoc) {
331             return (coll.contains(obj) ? 1 : 0);
332         }
333         if (coll instanceof Bag) {
334             return ((Bag) coll).getCount(obj);
335         }
336         int count = 0;
337         if (obj == null) {
338             for (Iterator JavaDoc it = coll.iterator();it.hasNext();) {
339                 if (it.next() == null) {
340                     count++;
341                 }
342             }
343         } else {
344             for (Iterator JavaDoc it = coll.iterator();it.hasNext();) {
345                 if (obj.equals(it.next())) {
346                     count++;
347                 }
348             }
349         }
350         return count;
351     }
352
353     /**
354      * Finds the first element in the given collection which matches the given predicate.
355      * <p>
356      * If the input collection or predicate is null, or no element of the collection
357      * matches the predicate, null is returned.
358      *
359      * @param collection the collection to search, may be null
360      * @param predicate the predicate to use, may be null
361      * @return the first element of the collection which matches the predicate or null if none could be found
362      */

363     public static Object JavaDoc find(Collection JavaDoc collection, Predicate predicate) {
364         if (collection != null && predicate != null) {
365             for (Iterator JavaDoc iter = collection.iterator(); iter.hasNext();) {
366                 Object JavaDoc item = iter.next();
367                 if (predicate.evaluate(item)) {
368                     return item;
369                 }
370             }
371         }
372         return null;
373     }
374     
375     /**
376      * Executes the given closure on each element in the collection.
377      * <p>
378      * If the input collection or closure is null, there is no change made.
379      *
380      * @param collection the collection to get the input from, may be null
381      * @param closure the closure to perform, may be null
382      */

383     public static void forAllDo(Collection JavaDoc collection, Closure closure) {
384         if (collection != null && closure != null) {
385             for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
386                 closure.execute(it.next());
387             }
388         }
389     }
390
391     /**
392      * Filter the collection by applying a Predicate to each element. If the
393      * predicate returns false, remove the element.
394      * <p>
395      * If the input collection or predicate is null, there is no change made.
396      *
397      * @param collection the collection to get the input from, may be null
398      * @param predicate the predicate to use as a filter, may be null
399      */

400     public static void filter(Collection JavaDoc collection, Predicate predicate) {
401         if (collection != null && predicate != null) {
402             for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
403                 if (predicate.evaluate(it.next()) == false) {
404                     it.remove();
405                 }
406             }
407         }
408     }
409
410     /**
411      * Transform the collection by applying a Transformer to each element.
412      * <p>
413      * If the input collection or transformer is null, there is no change made.
414      * <p>
415      * This routine is best for Lists, for which set() is used to do the
416      * transformations "in place." For other Collections, clear() and addAll()
417      * are used to replace elements.
418      * <p>
419      * If the input collection controls its input, such as a Set, and the
420      * Transformer creates duplicates (or are otherwise invalid), the
421      * collection may reduce in size due to calling this method.
422      *
423      * @param collection the collection to get the input from, may be null
424      * @param transformer the transformer to perform, may be null
425      */

426     public static void transform(Collection JavaDoc collection, Transformer transformer) {
427         if (collection != null && transformer != null) {
428             if (collection instanceof List JavaDoc) {
429                 List JavaDoc list = (List JavaDoc) collection;
430                 for (ListIterator JavaDoc it = list.listIterator(); it.hasNext();) {
431                     it.set(transformer.transform(it.next()));
432                 }
433             } else {
434                 Collection JavaDoc resultCollection = collect(collection, transformer);
435                 collection.clear();
436                 collection.addAll(resultCollection);
437             }
438         }
439     }
440
441     /**
442      * Counts the number of elements in the input collection that match the predicate.
443      * <p>
444      * A <code>null</code> collection or predicate matches no elements.
445      *
446      * @param inputCollection the collection to get the input from, may be null
447      * @param predicate the predicate to use, may be null
448      * @return the number of matches for the predicate in the collection
449      */

450     public static int countMatches(Collection JavaDoc inputCollection, Predicate predicate) {
451         int count = 0;
452         if (inputCollection != null && predicate != null) {
453             for (Iterator JavaDoc it = inputCollection.iterator(); it.hasNext();) {
454                 if (predicate.evaluate(it.next())) {
455                     count++;
456                 }
457             }
458         }
459         return count;
460     }
461
462     /**
463      * Answers true if a predicate is true for at least one element of a collection.
464      * <p>
465      * A <code>null</code> collection or predicate returns false.
466      *
467      * @param collection the collection to get the input from, may be null
468      * @param predicate the predicate to use, may be null
469      * @return true if at least one element of the collection matches the predicate
470      */

471     public static boolean exists(Collection JavaDoc collection, Predicate predicate) {
472         if (collection != null && predicate != null) {
473             for (Iterator JavaDoc it = collection.iterator(); it.hasNext();) {
474                 if (predicate.evaluate(it.next())) {
475                     return true;
476                 }
477             }
478         }
479         return false;
480     }
481
482     /**
483      * Selects all elements from input collection which match the given predicate
484      * into an output collection.
485      * <p>
486      * A <code>null</code> predicate matches no elements.
487      *
488      * @param inputCollection the collection to get the input from, may not be null
489      * @param predicate the predicate to use, may be null
490      * @return the elements matching the predicate (new list)
491      * @throws NullPointerException if the input collection is null
492      */

493     public static Collection JavaDoc select(Collection JavaDoc inputCollection, Predicate predicate) {
494         ArrayList JavaDoc answer = new ArrayList JavaDoc(inputCollection.size());
495         select(inputCollection, predicate, answer);
496         return answer;
497     }
498
499     /**
500      * Selects all elements from input collection which match the given predicate
501      * and adds them to outputCollection.
502      * <p>
503      * If the input collection or predicate is null, there is no change to the
504      * output collection.
505      *
506      * @param inputCollection the collection to get the input from, may be null
507      * @param predicate the predicate to use, may be null
508      * @param outputCollection the collection to output into, may not be null
509      */

510     public static void select(Collection JavaDoc inputCollection, Predicate predicate, Collection JavaDoc outputCollection) {
511         if (inputCollection != null && predicate != null) {
512             for (Iterator JavaDoc iter = inputCollection.iterator(); iter.hasNext();) {
513                 Object JavaDoc item = iter.next();
514                 if (predicate.evaluate(item)) {
515                     outputCollection.add(item);
516                 }
517             }
518         }
519     }
520     
521     /**
522      * Selects all elements from inputCollection which don't match the given predicate
523      * into an output collection.
524      * <p>
525      * If the input predicate is <code>null</code>, the result is an empty list.
526      *
527      * @param inputCollection the collection to get the input from, may not be null
528      * @param predicate the predicate to use, may be null
529      * @return the elements <b>not</b> matching the predicate (new list)
530      * @throws NullPointerException if the input collection is null
531      */

532     public static Collection JavaDoc selectRejected(Collection JavaDoc inputCollection, Predicate predicate) {
533         ArrayList JavaDoc answer = new ArrayList JavaDoc(inputCollection.size());
534         selectRejected(inputCollection, predicate, answer);
535         return answer;
536     }
537     
538     /**
539      * Selects all elements from inputCollection which don't match the given predicate
540      * and adds them to outputCollection.
541      * <p>
542      * If the input predicate is <code>null</code>, no elements are added to <code>outputCollection</code>.
543      *
544      * @param inputCollection the collection to get the input from, may be null
545      * @param predicate the predicate to use, may be null
546      * @param outputCollection the collection to output into, may not be null
547      */

548     public static void selectRejected(Collection JavaDoc inputCollection, Predicate predicate, Collection JavaDoc outputCollection) {
549         if (inputCollection != null && predicate != null) {
550             for (Iterator JavaDoc iter = inputCollection.iterator(); iter.hasNext();) {
551                 Object JavaDoc item = iter.next();
552                 if (predicate.evaluate(item) == false) {
553                     outputCollection.add(item);
554                 }
555             }
556         }
557     }
558     
559     /**
560      * Returns a new Collection consisting of the elements of inputCollection transformed
561      * by the given transformer.
562      * <p>
563      * If the input transformer is null, the result is an empty list.
564      *
565      * @param inputCollection the collection to get the input from, may not be null
566      * @param transformer the transformer to use, may be null
567      * @return the transformed result (new list)
568      * @throws NullPointerException if the input collection is null
569      */

570     public static Collection JavaDoc collect(Collection JavaDoc inputCollection, Transformer transformer) {
571         ArrayList JavaDoc answer = new ArrayList JavaDoc(inputCollection.size());
572         collect(inputCollection, transformer, answer);
573         return answer;
574     }
575     
576     /**
577      * Transforms all elements from the inputIterator with the given transformer
578      * and adds them to the outputCollection.
579      * <p>
580      * If the input iterator or transformer is null, the result is an empty list.
581      *
582      * @param inputIterator the iterator to get the input from, may be null
583      * @param transformer the transformer to use, may be null
584      * @return the transformed result (new list)
585      */

586     public static Collection JavaDoc collect(Iterator JavaDoc inputIterator, Transformer transformer) {
587         ArrayList JavaDoc answer = new ArrayList JavaDoc();
588         collect(inputIterator, transformer, answer);
589         return answer;
590     }
591     
592     /**
593      * Transforms all elements from inputCollection with the given transformer
594      * and adds them to the outputCollection.
595      * <p>
596      * If the input collection or transformer is null, there is no change to the
597      * output collection.
598      *
599      * @param inputCollection the collection to get the input from, may be null
600      * @param transformer the transformer to use, may be null
601      * @param outputCollection the collection to output into, may not be null
602      * @return the outputCollection with the transformed input added
603      * @throws NullPointerException if the output collection is null
604      */

605     public static Collection JavaDoc collect(Collection JavaDoc inputCollection, final Transformer transformer, final Collection JavaDoc outputCollection) {
606         if (inputCollection != null) {
607             return collect(inputCollection.iterator(), transformer, outputCollection);
608         }
609         return outputCollection;
610     }
611
612     /**
613      * Transforms all elements from the inputIterator with the given transformer
614      * and adds them to the outputCollection.
615      * <p>
616      * If the input iterator or transformer is null, there is no change to the
617      * output collection.
618      *
619      * @param inputIterator the iterator to get the input from, may be null
620      * @param transformer the transformer to use, may be null
621      * @param outputCollection the collection to output into, may not be null
622      * @return the outputCollection with the transformed input added
623      * @throws NullPointerException if the output collection is null
624      */

625     public static Collection JavaDoc collect(Iterator JavaDoc inputIterator, final Transformer transformer, final Collection JavaDoc outputCollection) {
626         if (inputIterator != null && transformer != null) {
627             while (inputIterator.hasNext()) {
628                 Object JavaDoc item = inputIterator.next();
629                 Object JavaDoc value = transformer.transform(item);
630                 outputCollection.add(value);
631             }
632         }
633         return outputCollection;
634     }
635
636     /**
637      * Adds all elements in the iteration to the given collection.
638      *
639      * @param collection the collection to add to
640      * @param iterator the iterator of elements to add, may not be null
641      * @throws NullPointerException if the collection or iterator is null
642      */

643     public static void addAll(Collection JavaDoc collection, Iterator JavaDoc iterator) {
644         while (iterator.hasNext()) {
645             collection.add(iterator.next());
646         }
647     }
648     
649     /**
650      * Adds all elements in the enumeration to the given collection.
651      *
652      * @param collection the collection to add to
653      * @param enumeration the enumeration of elements to add, may not be null
654      * @throws NullPointerException if the collection or enumeration is null
655      */

656     public static void addAll(Collection JavaDoc collection, Enumeration JavaDoc enumeration) {
657         while (enumeration.hasMoreElements()) {
658             collection.add(enumeration.nextElement());
659         }
660     }
661     
662     /**
663      * Adds all elements in the array to the given collection.
664      *
665      * @param collection the collection to add to, may not be null
666      * @param elements the array of elements to add, may not be null
667      * @throws NullPointerException if the collection or array is null
668      */

669     public static void addAll(Collection JavaDoc collection, Object JavaDoc[] elements) {
670         for (int i = 0, size = elements.length; i < size; i++) {
671             collection.add(elements[i]);
672         }
673     }
674     
675     /**
676      * Given an Object, and an index, returns the nth value in the
677      * object.
678      * <ul>
679      * <li>If obj is a Map, returns the nth value from the <b>keySet</b> iterator, unless
680      * the Map contains an Integer key with integer value = idx, in which case the
681      * corresponding map entry value is returned. If idx exceeds the number of entries in
682      * the map, an empty Iterator is returned.
683      * <li>If obj is a List or an array, returns the nth value, throwing IndexOutOfBoundsException,
684      * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
685      * <li>If obj is an iterator, enumeration or Collection, returns the nth value from the iterator,
686      * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
687      * <li>Returns the original obj if it is null or not a Collection or Iterator.
688      * </ul>
689      *
690      * @param obj the object to get an index of, may be null
691      * @param idx the index to get
692      * @throws IndexOutOfBoundsException
693      * @throws ArrayIndexOutOfBoundsException
694      *
695      * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
696      */

697     public static Object JavaDoc index(Object JavaDoc obj, int idx) {
698         return index(obj, new Integer JavaDoc(idx));
699     }
700     
701     /**
702      * Given an Object, and a key (index), returns the value associated with
703      * that key in the Object. The following checks are made:
704      * <ul>
705      * <li>If obj is a Map, use the index as a key to get a value. If no match continue.
706      * <li>Check key is an Integer. If not, return the object passed in.
707      * <li>If obj is a Map, get the nth value from the <b>keySet</b> iterator.
708      * If the Map has fewer than n entries, return an empty Iterator.
709      * <li>If obj is a List or an array, get the nth value, throwing IndexOutOfBoundsException,
710      * ArrayIndexOutOfBoundsException, resp. if the nth value does not exist.
711      * <li>If obj is an iterator, enumeration or Collection, get the nth value from the iterator,
712      * returning an empty Iterator (resp. Enumeration) if the nth value does not exist.
713      * <li>Return the original obj.
714      * </ul>
715      *
716      * @param obj the object to get an index of
717      * @param index the index to get
718      * @return the object at the specified index
719      * @throws IndexOutOfBoundsException
720      * @throws ArrayIndexOutOfBoundsException
721      *
722      * @deprecated use {@link #get(Object, int)} instead. Will be removed in v4.0
723      */

724     public static Object JavaDoc index(Object JavaDoc obj, Object JavaDoc index) {
725         if(obj instanceof Map JavaDoc) {
726             Map JavaDoc map = (Map JavaDoc)obj;
727             if(map.containsKey(index)) {
728                 return map.get(index);
729             }
730         }
731         int idx = -1;
732         if(index instanceof Integer JavaDoc) {
733             idx = ((Integer JavaDoc)index).intValue();
734         }
735         if(idx < 0) {
736             return obj;
737         }
738         else if(obj instanceof Map JavaDoc) {
739             Map JavaDoc map = (Map JavaDoc)obj;
740             Iterator JavaDoc iterator = map.keySet().iterator();
741             return index(iterator, idx);
742         }
743         else if(obj instanceof List JavaDoc) {
744             return ((List JavaDoc)obj).get(idx);
745         }
746         else if(obj instanceof Object JavaDoc[]) {
747             return ((Object JavaDoc[])obj)[idx];
748         }
749         else if(obj instanceof Enumeration JavaDoc) {
750             Enumeration JavaDoc it = (Enumeration JavaDoc)obj;
751             while(it.hasMoreElements()) {
752                 idx--;
753                 if(idx == -1) {
754                     return it.nextElement();
755                 } else {
756                     it.nextElement();
757                 }
758             }
759         }
760         else if(obj