001    /*
002     * Created on Apr 29, 2007
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     * 
007     * http://www.apache.org/licenses/LICENSE-2.0
008     * 
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     * 
013     * Copyright @2007-2011 the original author or authors.
014     */
015    package org.fest.util;
016    
017    import static java.util.Collections.*;
018    
019    import static org.fest.util.ToString.toStringOf;
020    
021    import java.util.ArrayList;
022    import java.util.Collection;
023    import java.util.HashSet;
024    import java.util.Iterator;
025    import java.util.LinkedHashSet;
026    import java.util.List;
027    import java.util.Set;
028    
029    /**
030     * Utility methods related to collections.
031     * 
032     * @author Yvonne Wang
033     * @author Alex Ruiz
034     * @author Joel Costigliola
035     */
036    public final class Collections {
037    
038      /**
039       * Creates a list containing the given elements.
040       * @param <T> the type of elements of the list to create.
041       * @param elements the elements to store in the list.
042       * @return the created list.
043       */
044      public static <T> List<T> list(T... elements) {
045        if (elements == null) return null;
046        List<T> list = new ArrayList<T>();
047        for (T e : elements)
048          list.add(e);
049        return list;
050      }
051    
052      /**
053       * Creates a set containing the given elements.
054       * @param <T> the type of elements of the set to create.
055       * @param elements the elements to store in the set.
056       * @return the created set.
057       * @since 1.1.5
058       */
059      public static <T> Set<T> set(T... elements) {
060        if (elements == null) return null;
061        Set<T> set = new LinkedHashSet<T>();
062        for (T e : elements)
063          set.add(e);
064        return set;
065      }
066    
067      /**
068       * Returns any duplicate elements from the given collection.
069       * @param <T> the generic type of the given collection.
070       * @param c the given collection that might have duplicate elements.
071       * @return a collection containing the duplicate elements of the given one. If no duplicates are found, an empty
072       *         collection is returned.
073       */
074      public static <T> Collection<T> duplicatesFrom(Collection<T> c) {
075        Set<T> duplicates = new HashSet<T>();
076        if (isEmpty(c)) return duplicates;
077        Set<T> noDuplicates = new HashSet<T>();
078        for (T e : c) {
079          if (noDuplicates.contains(e)) {
080            duplicates.add(e);
081            continue;
082          }
083          noDuplicates.add(e);
084        }
085        return duplicates;
086      }
087    
088      /**
089       * Returns {@code true} if the given {@link Iterable} is {@code null} or empty.
090       * @param iterable the {@link Iterable} to check.
091       * @return {@code true} if the given {@link Iterable} is {@code null} or empty, otherwise {@code false}.
092       */
093      public static boolean isEmpty(Iterable<?> iterable) {
094        return iterable == null || !iterable.iterator().hasNext();
095      }
096    
097      /**
098       * Returns the size of the given {@link Iterable}.
099       * @param iterable the {@link Iterable} to get size.
100       * @return the size of the given {@link Iterable}..
101       * @throws IllegalArgumentException if given {@link Iterable} is null.
102       */
103      public static int sizeOf(Iterable<?> iterable) {
104        if (iterable == null) throw new IllegalArgumentException("iterable parameter must not be null");
105        int size = 0;
106        for (@SuppressWarnings("unused") Object object : iterable) {
107          size++;
108        }
109        return size;
110      }
111      
112      public static <T> List<T> filter(Collection<?> target, CollectionFilter<T> filter) {
113        return filter.filter(target);
114      }
115    
116      /**
117       * Returns the {@code String} representation of the given collection, or {@code null} if the given collection is
118       * {@code null}.
119       * @param c the collection to format.
120       * @return the {@code String} representation of the given collection.
121       */
122      public static String format(Collection<?> c) {
123        if (c == null) return null;
124        Iterator<?> i = c.iterator();
125        if (!i.hasNext()) return "[]";
126        StringBuilder b = new StringBuilder();
127        b.append('[');
128        for (;;) {
129          Object e = i.next();
130          b.append(e == c ? "(this Collection)" : toStringOf(e));
131          if (!i.hasNext()) return b.append(']').toString();
132          b.append(", ");
133        }
134      }
135    
136      /**
137       * Returns a new unmodifiable collection containing the non-null elements of the given collection. This method returns
138       * an empty unmodifiable collection if the given collection has only {@code null} elements or if it is empty. This
139       * method returns {@code null} if the given collection is {@code null}.
140       * @param <T> the type of elements of the collection.
141       * @param c the collection we want to extract non null elements from.
142       * @return a new unmodifiable collection containing the non-null elements of the given collection, or {@code null} if
143       *         the given collection is {@code null}.
144       * @since 1.1.3
145       */
146      public static <T> Collection<T> nonNullElements(Collection<T> c) {
147        if (c == null) return null;
148        Collection<T> nonNullElements = new ArrayList<T>();
149        for (T o : c)
150          if (o != null) nonNullElements.add(o);
151        return unmodifiableCollection(nonNullElements);
152      }
153    
154      /**
155       * Returns a new unmodifiable list containing the non-null elements of the given list. This method returns an empty
156       * unmodifiable list if the given list has only {@code null} elements or if it is empty. This method returns
157       * {@code null} if the given list is {@code null}.
158       * @param <T> the type of elements of the list.
159       * @param l the list we want to extract non null elements from.
160       * @return a new unmodifiable list containing the non-null elements of the given list, or {@code null} if the given
161       *         list is {@code null}.
162       * @since 1.1.3
163       */
164      public static <T> List<T> nonNullElements(List<T> l) {
165        Collection<T> nonNullElements = nonNullElements((Collection<T>) l);
166        if (nonNullElements == null) return null;
167        return unmodifiableList(new ArrayList<T>(nonNullElements));
168      }
169    
170      /**
171       * Returns {@code true} if the given {@link Iterable} has only {@code null} elements, {@code false} otherwise. If given
172       * {@link Iterable} is empty, this method returns {@code true}.
173       * @param iterable the given iterable. <b>It must not be null</b>.
174       * @return {@code true} if the given iterable has only {@code null} elements or is empty, {@code false} otherwise.
175       * @throws NullPointerException if the given iterable is {@code null}.
176       * @since 1.1.3
177       */
178      public static boolean hasOnlyNullElements(Iterable<?> iterable) {
179        if (iterable == null) throw new NullPointerException("The iterable to check should not be null");
180        if (isEmpty(iterable)) return false;
181        for (Object element : iterable)
182          if (element != null) return false;
183        return true;
184      }
185    
186      /**
187       * Creates a list containing the given {@link Iterable} elements.
188       * @param <T> the type of elements of the list to create.
189       * @param iterable the {@link Iterable} to get elements from to store in the list.
190       * @return the created list.
191       */
192      public static <T> List<T> list(Iterable<T> iterable) {
193        if (iterable == null) return null;
194        List<T> list = new ArrayList<T>();
195        for (T e : iterable)
196          list.add(e);
197        return list;
198      }
199    
200      private Collections() {}
201    }