001 /*--------------------------------------------------------------------------+
002 $Id: CollectionUtils.java 27324 2010-03-31 08:53:26Z hummelb $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.collections;
019
020 import java.util.ArrayList;
021 import java.util.Arrays;
022 import java.util.Collection;
023 import java.util.Collections;
024 import java.util.Comparator;
025 import java.util.Deque;
026 import java.util.HashSet;
027 import java.util.Iterator;
028 import java.util.List;
029 import java.util.Map;
030 import java.util.Set;
031 import java.util.SortedMap;
032 import java.util.SortedSet;
033
034 /**
035 * This class offers utility methods for collections. In can be seen as an
036 * extension to {@link Collections}.
037 *
038 * @author Florian Deissenboeck
039 * @author $Author: hummelb $
040 *
041 * @version $Revision: 27324 $
042 * @levd.rating GREEN Hash: 18A8495D2E7BB7DE351987B60C0E3338
043 */
044 public class CollectionUtils {
045 /** Empty unmodifiable list. */
046 @SuppressWarnings("unchecked")
047 private static final UnmodifiableList<?> EMPTY_LIST = new UnmodifiableList<Object>(
048 Collections.EMPTY_LIST);
049
050 /** Empty unmodifiable map. */
051 @SuppressWarnings("unchecked")
052 private static final UnmodifiableMap<?, ?> EMPTY_MAP = new UnmodifiableMap<Object, Object>(
053 Collections.EMPTY_MAP);
054
055 /** Empty unmodifiable set. */
056 @SuppressWarnings("unchecked")
057 private static final UnmodifiableSet<?> EMPTY_SET = new UnmodifiableSet<Object>(
058 Collections.EMPTY_SET);
059
060 /**
061 * Create an hashed set from an array.
062 *
063 * @param <T>
064 * type
065 * @param elements
066 * elements in the set.
067 * @return the set.
068 * @see Arrays#asList(Object[])
069 */
070 public static <T> HashSet<T> asHashSet(T... elements) {
071 HashSet<T> result = new HashSet<T>();
072
073 Collections.addAll(result, elements);
074
075 return result;
076 }
077
078 /**
079 * Returns a new unmodifiable collection wrapping the given collection. This
080 * method is here to avoid retyping the generic argument for the collection
081 * class.
082 */
083 public static <T> UnmodifiableCollection<T> asUnmodifiable(Collection<T> c) {
084 return new UnmodifiableCollection<T>(c);
085 }
086
087 /**
088 * Returns a new unmodifiable hashed list map wrapping the given map. This
089 * method is here to avoid retyping the generic arguments for the sorted map
090 * class.
091 */
092 public static <S, T> UnmodifiableHashedListMap<S, T> asUnmodifiable(
093 HashedListMap<S, T> m) {
094 return new UnmodifiableHashedListMap<S, T>(m);
095 }
096
097 /**
098 * Returns a new unmodifiable list wrapping the given list. This method is
099 * here to avoid retyping the generic argument for the list class.
100 */
101 public static <T> UnmodifiableList<T> asUnmodifiable(List<T> l) {
102 return new UnmodifiableList<T>(l);
103 }
104
105 /**
106 * Returns a new unmodifiable map wrapping the given map. This method is
107 * here to avoid retyping the generic arguments for the map class.
108 */
109 public static <S, T> UnmodifiableMap<S, T> asUnmodifiable(Map<S, T> m) {
110 return new UnmodifiableMap<S, T>(m);
111 }
112
113 /**
114 * Returns a new unmodifiable set wrapping the given set. This method is
115 * here to avoid retyping the generic argument for the set class.
116 */
117 public static <T> UnmodifiableSet<T> asUnmodifiable(Set<T> s) {
118 return new UnmodifiableSet<T>(s);
119 }
120
121 /**
122 * Returns a new unmodifiable sorted map wrapping the given sorted map. This
123 * method is here to avoid retyping the generic arguments for the sorted map
124 * class.
125 */
126 public static <S, T> UnmodifiableSortedMap<S, T> asUnmodifiable(
127 SortedMap<S, T> m) {
128 return new UnmodifiableSortedMap<S, T>(m);
129 }
130
131 /**
132 * Returns a new unmodifiable sorted set wrapping the given sorted set. This
133 * method is here to avoid retyping the generic argument for the sorted set
134 * class.
135 */
136 public static <T> UnmodifiableSortedSet<T> asUnmodifiable(SortedSet<T> s) {
137 return new UnmodifiableSortedSet<T>(s);
138 }
139
140 /**
141 * The way this method is defined allows to assign it to all parameterized
142 * types, i.e. bot of the following statements are accepted by the compiler
143 * without warnings:
144 *
145 * <pre>
146 * UnmodifiableList<String> emptyList = CollectionUtils.emptyList();
147 *
148 * UnmodifiableList<Date> emptyList = CollectionUtils.emptyList();
149 * </pre>
150 *
151 * @param <T>
152 * @return the emtpy list
153 */
154 @SuppressWarnings("unchecked")
155 public static final <T> UnmodifiableList<T> emptyList() {
156 return (UnmodifiableList<T>) EMPTY_LIST;
157 }
158
159 /** Returns an empty map. See {@link #emptyList()} for further details. */
160 @SuppressWarnings("unchecked")
161 public static final <S, T> UnmodifiableMap<S, T> emptyMap() {
162 return (UnmodifiableMap<S, T>) EMPTY_MAP;
163 }
164
165 /** Returns an empty set. See {@link #emptyList()} for further details. */
166 @SuppressWarnings("unchecked")
167 public static final <T> UnmodifiableSet<T> emptySet() {
168 return (UnmodifiableSet<T>) EMPTY_SET;
169 }
170
171 /**
172 * Sorts the specified list into ascending order, according to the
173 * <i>natural ordering</i> of its elements.
174 * <p>
175 * All elements in the list must implement the Comparable interface.
176 * Furthermore, all elements in the list must be mutually comparable (that
177 * is, e1.compareTo(e2) must not throw a <code>ClassCastException</code> for
178 * any elements e1 and e2 in the list).
179 * <p>
180 * This method does not modify the original collection.
181 */
182 public static <T extends Comparable<? super T>> List<T> sort(
183 Collection<T> collection) {
184 ArrayList<T> list = new ArrayList<T>(collection);
185 Collections.sort(list);
186 return list;
187 }
188
189 /**
190 * Returns a list that contains the elements of the specified list in
191 * reversed order.
192 * <p>
193 * This method does not modify the original collection.
194 */
195 public static <T> List<T> reverse(Collection<T> list) {
196 ArrayList<T> reversed = new ArrayList<T>(list);
197 Collections.reverse(reversed);
198 return reversed;
199 }
200
201 /**
202 * Sorts the specified list according to the order induced by the specified
203 * comparator.
204 * <p>
205 * All elements in the list must implement the Comparable interface.
206 * Furthermore, all elements in the list must be mutually comparable (that
207 * is, e1.compareTo(e2) must not throw a <code>ClassCastException</code> for
208 * any elements e1 and e2 in the list).
209 * <p>
210 * This method does not modify the original collection.
211 */
212 public static <T> List<T> sort(Collection<T> collection,
213 Comparator<? super T> comparator) {
214 ArrayList<T> list = new ArrayList<T>(collection);
215 Collections.sort(list, comparator);
216 return list;
217 }
218
219 /** Returns a sorted unmodifiable list for a collection. */
220 public static <T extends Comparable<T>> UnmodifiableList<T> asSortedUnmodifiableList(
221 Collection<T> collection) {
222 return asUnmodifiable(sort(collection));
223 }
224
225 /**
226 * Returns a sorted unmodifiable list for a collection.
227 *
228 * @param comparator
229 * Comparator used for sorting
230 */
231 public static <T extends Comparable<T>> UnmodifiableList<T> asSortedUnmodifiableList(
232 Collection<T> collection, Comparator<? super T> comparator) {
233 return asUnmodifiable(sort(collection, comparator));
234 }
235
236 /**
237 * Returns one object from an {@link Iterable} or <code>null</code> if the
238 * iterable is empty.
239 */
240 public static <T> T getAny(Iterable<T> iterable) {
241 Iterator<T> iterator = iterable.iterator();
242 if (!iterator.hasNext()) {
243 return null;
244 }
245 return iterator.next();
246 }
247
248 /**
249 * Convert collection to array. This is a bit cleaner version of
250 * {@link Collection#toArray(Object[])}.
251 */
252 @SuppressWarnings("unchecked")
253 public static <T> T[] toArray(Collection<? extends T> collection,
254 Class<T> type) {
255 T[] result = (T[]) java.lang.reflect.Array.newInstance(type, collection
256 .size());
257
258 Iterator<? extends T> it = collection.iterator();
259 for (int i = 0; i < collection.size(); i++) {
260 result[i] = it.next();
261 }
262
263 return result;
264 }
265
266 /**
267 * Copy an array. This is a shortcut for
268 * {@link Arrays#copyOf(Object[], int)} that does not require to specify the
269 * length.
270 */
271 public static <T> T[] copyArray(T[] original) {
272 return Arrays.copyOf(original, original.length);
273 }
274
275 /**
276 * Compute list of unordered pairs for all elements contained in a
277 * collection.
278 */
279 public static <T> List<ImmutablePair<T, T>> computeUnorderedPairs(
280 Collection<T> collection) {
281 List<T> elements = new ArrayList<T>(collection);
282 List<ImmutablePair<T, T>> pairs = new ArrayList<ImmutablePair<T, T>>();
283
284 int size = elements.size();
285 for (int firstIndex = 0; firstIndex < size; firstIndex++) {
286 for (int secondIndex = firstIndex + 1; secondIndex < size; secondIndex++) {
287 pairs.add(new ImmutablePair<T, T>(elements.get(firstIndex),
288 elements.get(secondIndex)));
289 }
290 }
291
292 return pairs;
293 }
294
295 /** Returns the last element in list or <code>null</code>, if list is empty. */
296 @SuppressWarnings("unchecked")
297 public static <T> T getLast(List<T> list) {
298 if (list.isEmpty()) {
299 return null;
300 }
301 if (list instanceof Deque<?>) {
302 return ((Deque<T>) list).getLast();
303 }
304 return list.get(list.size() - 1);
305 }
306
307 }