KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.ArrayList JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23
24 import org.apache.commons.collections.list.FixedSizeList;
25 import org.apache.commons.collections.list.LazyList;
26 import org.apache.commons.collections.list.PredicatedList;
27 import org.apache.commons.collections.list.SynchronizedList;
28 import org.apache.commons.collections.list.TransformedList;
29 import org.apache.commons.collections.list.TypedList;
30 import org.apache.commons.collections.list.UnmodifiableList;
31
32 /**
33  * Provides utility methods and decorators for {@link List} instances.
34  *
35  * @since Commons Collections 1.0
36  * @version $Revision: 1.28 $ $Date: 2004/04/01 20:12:00 $
37  *
38  * @author Federico Barbieri
39  * @author Peter Donald
40  * @author Paul Jack
41  * @author Stephen Colebourne
42  * @author Neil O'Toole
43  * @author Matthew Hawthorne
44  */

45 public class ListUtils {
46
47     /**
48      * An empty unmodifiable list.
49      * This uses the {@link Collections Collections} implementation
50      * and is provided for completeness.
51      */

52     public static final List JavaDoc EMPTY_LIST = Collections.EMPTY_LIST;
53     
54     /**
55      * <code>ListUtils</code> should not normally be instantiated.
56      */

57     public ListUtils() {
58     }
59
60     //-----------------------------------------------------------------------
61
/**
62      * Returns a new list containing all elements that are contained in
63      * both given lists.
64      *
65      * @param list1 the first list
66      * @param list2 the second list
67      * @return the intersection of those two lists
68      * @throws NullPointerException if either list is null
69      */

70     public static List JavaDoc intersection(final List JavaDoc list1, final List JavaDoc list2) {
71         final ArrayList JavaDoc result = new ArrayList JavaDoc();
72         final Iterator JavaDoc iterator = list2.iterator();
73
74         while (iterator.hasNext()) {
75             final Object JavaDoc o = iterator.next();
76
77             if (list1.contains(o)) {
78                 result.add(o);
79             }
80         }
81
82         return result;
83     }
84
85     /**
86      * Subtracts all elements in the second list from the first list,
87      * placing the results in a new list.
88      * <p>
89      * This differs from {@link List#removeAll(Collection)} in that
90      * cardinality is respected; if <Code>list1</Code> contains two
91      * occurrences of <Code>null</Code> and <Code>list2</Code> only
92      * contains one occurrence, then the returned list will still contain
93      * one occurrence.
94      *
95      * @param list1 the list to subtract from
96      * @param list2 the list to subtract
97      * @return a new list containing the results
98      * @throws NullPointerException if either list is null
99      */

100     public static List JavaDoc subtract(final List JavaDoc list1, final List JavaDoc list2) {
101         final ArrayList JavaDoc result = new ArrayList JavaDoc(list1);
102         final Iterator JavaDoc iterator = list2.iterator();
103
104         while (iterator.hasNext()) {
105             result.remove(iterator.next());
106         }
107
108         return result;
109     }
110
111     /**
112      * Returns the sum of the given lists. This is their intersection
113      * subtracted from their union.
114      *
115      * @param list1 the first list
116      * @param list2 the second list
117      * @return a new list containing the sum of those lists
118      * @throws NullPointerException if either list is null
119      */

120     public static List JavaDoc sum(final List JavaDoc list1, final List JavaDoc list2) {
121         return subtract(union(list1, list2), intersection(list1, list2));
122     }
123
124     /**
125      * Returns a new list containing the second list appended to the
126      * first list. The {@link List#addAll(Collection)} operation is
127      * used to append the two given lists into a new list.
128      *
129      * @param list1 the first list
130      * @param list2 the second list
131      * @return a new list containing the union of those lists
132      * @throws NullPointerException if either list is null
133      */

134     public static List JavaDoc union(final List JavaDoc list1, final List JavaDoc list2) {
135         final ArrayList JavaDoc result = new ArrayList JavaDoc(list1);
136         result.addAll(list2);
137         return result;
138     }
139
140     /**
141      * Tests two lists for value-equality as per the equality contract in
142      * {@link java.util.List#equals(java.lang.Object)}.
143      * <p>
144      * This method is useful for implementing <code>List</code> when you cannot
145      * extend AbstractList. The method takes Collection instances to enable other
146      * collection types to use the List implementation algorithm.
147      * <p>
148      * The relevant text (slightly paraphrased as this is a static method) is:
149      * <blockquote>
150      * Compares the two list objects for equality. Returns
151      * <tt>true</tt> if and only if both
152      * lists have the same size, and all corresponding pairs of elements in
153      * the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
154      * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
155      * e1.equals(e2))</tt>.) In other words, two lists are defined to be
156      * equal if they contain the same elements in the same order. This
157      * definition ensures that the equals method works properly across
158      * different implementations of the <tt>List</tt> interface.
159      * </blockquote>
160      *
161      * <b>Note:</b> The behaviour of this method is undefined if the lists are
162      * modified during the equals comparison.
163      *
164      * @see java.util.List
165      * @param list1 the first list, may be null
166      * @param list2 the second list, may be null
167      * @return whether the lists are equal by value comparison
168      */

169     public static boolean isEqualList(final Collection JavaDoc list1, final Collection JavaDoc list2) {
170         if (list1 == list2) {
171             return true;
172         }
173         if (list1 == null || list2 == null || list1.size() != list2.size()) {
174             return false;
175         }
176
177         Iterator JavaDoc it1 = list1.iterator();
178         Iterator JavaDoc it2 = list2.iterator();
179         Object JavaDoc obj1 = null;
180         Object JavaDoc obj2 = null;
181
182         while (it1.hasNext() && it2.hasNext()) {
183             obj1 = it1.next();
184             obj2 = it2.next();
185
186             if (!(obj1 == null ? obj2 == null : obj1.equals(obj2))) {
187                 return false;
188             }
189         }
190
191         return !(it1.hasNext() || it2.hasNext());
192     }
193     
194     /**
195      * Generates a hash code using the algorithm specified in
196      * {@link java.util.List#hashCode()}.
197      * <p>
198      * This method is useful for implementing <code>List</code> when you cannot
199      * extend AbstractList. The method takes Collection instances to enable other
200      * collection types to use the List implementation algorithm.
201      *
202      * @see java.util.List#hashCode()
203      * @param list the list to generate the hashCode for, may be null
204      * @return the hash code
205      */

206     public static int hashCodeForList(final Collection JavaDoc list) {
207         if (list == null) {
208             return 0;
209         }
210         int hashCode = 1;
211         Iterator JavaDoc it = list.iterator();
212         Object JavaDoc obj = null;
213         
214         while (it.hasNext()) {
215             obj = it.next();
216             hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
217         }
218         return hashCode;
219     }
220
221     //-----------------------------------------------------------------------
222
/**
223      * Returns a synchronized list backed by the given list.
224      * <p>
225      * You must manually synchronize on the returned buffer's iterator to
226      * avoid non-deterministic behavior:
227      *
228      * <pre>
229      * List list = ListUtils.synchronizedList(myList);
230      * synchronized (list) {
231      * Iterator i = list.iterator();
232      * while (i.hasNext()) {
233      * process (i.next());
234      * }
235      * }
236      * </pre>
237      *
238      * This method uses the implementation in the decorators subpackage.
239      *
240      * @param list the list to synchronize, must not be null
241      * @return a synchronized list backed by the given list
242      * @throws IllegalArgumentException if the list is null
243      */

244     public static List JavaDoc synchronizedList(List JavaDoc list) {
245         return SynchronizedList.decorate(list);
246     }
247
248     /**
249      * Returns an unmodifiable list backed by the given list.
250      * <p>
251      * This method uses the implementation in the decorators subpackage.
252      *
253      * @param list the list to make unmodifiable, must not be null
254      * @return an unmodifiable list backed by the given list
255      * @throws IllegalArgumentException if the list is null
256      */

257     public static List JavaDoc unmodifiableList(List JavaDoc list) {
258         return UnmodifiableList.decorate(list);
259     }
260
261     /**
262      * Returns a predicated (validating) list backed by the given list.
263      * <p>
264      * Only objects that pass the test in the given predicate can be added to the list.
265      * Trying to add an invalid object results in an IllegalArgumentException.
266      * It is important not to use the original list after invoking this method,
267      * as it is a backdoor for adding invalid objects.
268      *
269      * @param list the list to predicate, must not be null
270      * @param predicate the predicate for the list, must not be null
271      * @return a predicated list backed by the given list
272      * @throws IllegalArgumentException if the List or Predicate is null
273      */

274     public static List JavaDoc predicatedList(List JavaDoc list, Predicate predicate) {
275         return PredicatedList.decorate(list, predicate);
276     }
277
278     /**
279      * Returns a typed list backed by the given list.
280      * <p>
281      * Only objects of the specified type can be added to the list.
282      *
283      * @param list the list to limit to a specific type, must not be null
284      * @param type the type of objects which may be added to the list
285      * @return a typed list backed by the specified list
286      */

287     public static List JavaDoc typedList(List JavaDoc list, Class JavaDoc type) {
288         return TypedList.decorate(list, type);
289     }
290     
291     /**
292      * Returns a transformed list backed by the given list.
293      * <p>
294      * Each object is passed through the transformer as it is added to the
295      * List. It is important not to use the original list after invoking this
296      * method, as it is a backdoor for adding untransformed objects.
297      *
298      * @param list the list to predicate, must not be null
299      * @param transformer the transformer for the list, must not be null
300      * @return a transformed list backed by the given list
301      * @throws IllegalArgumentException if the List or Transformer is null
302      */

303     public static List JavaDoc transformedList(List JavaDoc list, Transformer transformer) {
304         return TransformedList.decorate(list, transformer);
305     }
306     
307     /**
308      * Returns a "lazy" list whose elements will be created on demand.
309      * <p>
310      * When the index passed to the returned list's {@link List#get(int) get}
311      * method is greater than the list's size, then the factory will be used
312      * to create a new object and that object will be inserted at that index.
313      * <p>
314      * For instance:
315      *
316      * <pre>
317      * Factory factory = new Factory() {
318      * public Object create() {
319      * return new Date();
320      * }
321      * }
322      * List lazy = ListUtils.lazyList(new ArrayList(), factory);
323      * Object obj = lazy.get(3);
324      * </pre>
325      *
326      * After the above code is executed, <code>obj</code> will contain
327      * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
328      * instance is the fourth element in the list. The first, second,
329      * and third element are all set to <code>null</code>.
330      *
331      * @param list the list to make lazy, must not be null
332      * @param factory the factory for creating new objects, must not be null
333      * @return a lazy list backed by the given list
334      * @throws IllegalArgumentException if the List or Factory is null
335      */

336     public static List JavaDoc lazyList(List JavaDoc list, Factory factory) {
337         return LazyList.decorate(list, factory);
338     }
339
340     /**
341      * Returns a fixed-sized list backed by the given list.
342      * Elements may not be added or removed from the returned list, but
343      * existing elements can be changed (for instance, via the
344      * {@link List#set(int,Object)} method).
345      *
346      * @param list the list whose size to fix, must not be null
347      * @return a fixed-size list backed by that list
348      * @throws IllegalArgumentException if the List is null
349      */

350     public static List JavaDoc fixedSizeList(List JavaDoc list) {
351         return FixedSizeList.decorate(list);
352     }
353
354 }
355
Popular Tags