package com.softwaremill.common.util.collect;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.softwaremill.common.util.tuples.Pair;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.collect.Collections2.filter;
import static com.softwaremill.common.util.tuples.Pair.pair;
/**
* Common {@link java.util.Collection} helper methods
*
* @author Maciej Biłas
* @since 9/27/11 19:41
*/
public class Collections3 {
private Collections3() {
/* this class should not be instantiated */
}
/**
* Partitions a {@link Collection} according to the predicate.
*
* @param unpartitioned the unpartitioned collection
* @param predicate the predicate
* @param <E> type of collection's elements
* @return a pair of collections. The left element is satisfying the predicate, the right -- not.
* @throws NullPointerException if any of the arguments is {@code null}.
*/
public static <E> Pair<Collection<E>, Collection<E>> partition(Collection<E> unpartitioned,
Predicate<? super E> predicate) {
return pair(filter(checkNotNull(unpartitioned), checkNotNull(predicate)),
filter(unpartitioned, not(predicate)));
}
public static <T> Optional<T> findFirstInstanceOf(Collection<? super T> coll, Class<T> cls) {
for (Object o : coll) {
if (o != null && cls.isAssignableFrom(o.getClass())) {
//noinspection unchecked
return Optional.of((T) o);
}
}
return Optional.absent();
}
/**
* Returns the maximum element of the given collection, according to the
* order induced by the specified comparator.
* This method will neither throw {@link NullPointerException}
* nor {@link java.util.NoSuchElementException} if the provided collection is {@code null}
* or empty. In addition {@code null} elements are filtered from the collection.
*
* @param coll the collection whose maximum element is to be determined.
* @param comp the comparator with which to determine the maximum element.
* A <tt>null</tt> value indicates that the elements' <i>natural
* ordering</i> should be used.
* @return the maximum element of the given collection, according
* to the specified comparator or {@code null}
* if the input collection is {@code null} or empty.
* @throws ClassCastException if the collection contains elements that are
* not <i>mutually comparable</i> using the specified comparator.
* @see Comparable
*/
public static <T> T maxNullSafe(Collection<? extends T> coll, Comparator<? super T> comp) {
if (coll == null || coll.isEmpty())
return null;
Collection<? extends T> nullFiltered = filter(coll, notNull());
if (nullFiltered.isEmpty())
return null;
else
return Collections.max(nullFiltered, comp);
}
/**
* Returns the maximum element of the given collection, according to the
* <i>natural ordering</i> of its elements.
* This method will neither throw {@link NullPointerException}
* nor {@link java.util.NoSuchElementException} if the provided collection is {@code null}
* or empty. In addition {@code null} elements are filtered from the collection.
*
* @param coll the collection whose maximum element is to be determined.
* @return the maximum element of the given collection, according
* to the <i>natural ordering</i> of its elements or {@code null}
* if the input collection is {@code null} or empty.
* @throws ClassCastException if the collection contains elements that are
* not <i>mutually comparable</i> (for example, strings and
* integers).
* @see Comparable
*/
public static <T extends Object & Comparable<? super T>> T maxNullSafe(Collection<? extends T> coll) {
if (coll == null || coll.isEmpty())
return null;
Collection<? extends T> nullFiltered = filter(coll, notNull());
if (nullFiltered.isEmpty())
return null;
else
return Collections.max(nullFiltered);
}
}