Created
          April 15, 2015 14:09 
        
      - 
      
- 
        Save dominicthomas/9530f720519b074ec945 to your computer and use it in GitHub Desktop. 
    Stuff Guava is Missing
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | import static com.google.common.base.Optional.of; | |
| import static com.google.common.collect.Iterables.concat; | |
| import static com.google.common.collect.Iterables.filter; | |
| import static com.google.common.collect.Iterables.isEmpty; | |
| import static com.google.common.collect.Iterables.transform; | |
| import java.util.ArrayList; | |
| import java.util.Collection; | |
| import java.util.Comparator; | |
| import com.google.common.base.Function; | |
| import com.google.common.base.Optional; | |
| import com.google.common.base.Predicate; | |
| import com.google.common.base.Predicates; | |
| import com.google.common.collect.ImmutableSortedSet; | |
| import com.google.common.collect.Lists; | |
| import com.google.common.collect.Multimaps; | |
| import com.google.common.collect.Sets; | |
| import edu.umd.cs.findbugs.annotations.NonNull; | |
| /** | |
| * A Bunch of generic collection stuff that really should have been in Guava. | |
| */ | |
| public class CollectionUtil { | |
| private CollectionUtil() { | |
| } | |
| /** | |
| * Flattens a list of lists into a single list. | |
| * Like flatMap in Scala or bind in Haskell, but restricted to Iterables only thanks to Java's laughable type system. | |
| */ | |
| public static <A, B> Iterable<B> flatTransform(Iterable<A> i, Function<? super A, ? extends Iterable<B>> f) { | |
| return concat(transform(i, f)); | |
| } | |
| /** | |
| * Groups elements into a list of lists, with grouping determined by the given function. | |
| * | |
| * @param i the elements to group | |
| * @param f determines the property to group by | |
| * @return A list of grouped elements. | |
| */ | |
| public static <A, B> Collection<? extends Collection<? extends A>> group(Iterable<? extends A> i, | |
| Function<A, B> f) { | |
| return Multimaps.index(i, f).asMap().values(); | |
| } | |
| /** | |
| * Left Fold. | |
| * (a, b, c, d), initial -> f(f(f(f(initial,a), b), c), d) | |
| * http://en.wikipedia.org/wiki/Fold_(higher-order_function) | |
| */ | |
| public static <A, B> A fold(final Iterable<? extends B> gen, final A initial, | |
| final Function2<? super A, ? super B, ? extends A> function) { | |
| final Iterator<? extends B> it = gen.iterator(); | |
| if (!it.hasNext()) { | |
| return initial; | |
| } | |
| A acc = initial; | |
| while (it.hasNext()) { | |
| acc = function.apply(acc, it.next()); | |
| } | |
| return acc; | |
| } | |
| /** | |
| * A transformation function of arity-2 (two arguments) from A and B to C. | |
| */ | |
| public interface Function2<A, B, C> { | |
| C apply(A a, B b); | |
| } | |
| /** | |
| * Sums Integers. | |
| * @param ints a collection of {@code Integer} objects | |
| * @return sum of ints | |
| * @throws NullPointerException if {@code ints} or any of its elements is null | |
| */ | |
| public static int sum(@NonNull Iterable<Integer> ints) { | |
| int sum = 0; | |
| for (int anInt : ints) { | |
| sum += anInt; | |
| } | |
| return sum; | |
| } | |
| /** | |
| * Returns true if all {@code B}s are equal | |
| */ | |
| public static <A, B> boolean allEqual(Iterable<A> iterable, Function<A, B> function) { | |
| return allEqual(transform(iterable, function)); | |
| } | |
| /** | |
| * Returns true if all elements in the List are equal | |
| */ | |
| public static boolean allEqual(Iterable<?> iterable) { | |
| return Sets.newHashSet(iterable).size() < 2; | |
| } | |
| /** | |
| * Returns the count of unique {@code A}s according to supplied comparator | |
| */ | |
| public static <A> int countDistinct(Iterable<A> iterable, Comparator<? super A> comparator) { | |
| return ImmutableSortedSet.copyOf(comparator, iterable).size(); | |
| } | |
| /** | |
| * Returns a list with duplicates removed according to the given comparator. | |
| */ | |
| public static <A> Iterable<A> distinct(Iterable<A> iterable, Comparator<? super A> comparator) { | |
| return ImmutableSortedSet.copyOf(comparator, iterable); | |
| } | |
| /** | |
| * Determines if the given iterable contains no elements. | |
| */ | |
| public static boolean isNotEmpty(Iterable<?> iterable) { | |
| return !isEmpty(iterable); | |
| } | |
| /** | |
| * Returns true if the predicate holds for at least one of the elements of this iterable, false otherwise | |
| * (false for the empty list). | |
| */ | |
| public static <A> boolean exists(Iterable<A> iterable, Predicate<A> predicate) { | |
| return isNotEmpty(filter(iterable, predicate)); | |
| } | |
| /** | |
| * Returns true if the iterable has at least one element whose class is {@code type} or a subclass of {@code type}. | |
| */ | |
| public static boolean exists(Iterable<?> iterable, Class<?> type) { | |
| return isNotEmpty(filter(iterable, type)); | |
| } | |
| /** | |
| * Syntactic sugar for Guava's Predicates.in() | |
| */ | |
| public static <T> Predicate<T> in(T... target) { | |
| return Predicates.in(Lists.newArrayList(target)); | |
| } | |
| /** | |
| * Simply returns a new Iterable with each element wrapped in an Optional. | |
| */ | |
| public static <A> Iterable<Optional<A>> asOptionalList(Iterable<A> iterable) { | |
| Collection<Optional<A>> list = new ArrayList<Optional<A>>(); | |
| for (A a : iterable) { | |
| list.add(of(a)); | |
| } | |
| return list; | |
| } | |
| /** | |
| * Creates a Guava multimap using the input map. | |
| */ | |
| public static <K, V> Multimap<K, V> createMultiMap(Map<K, ? extends Iterable<V>> input) { | |
| Multimap<K, V> multimap = ArrayListMultimap.create(); | |
| for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) { | |
| multimap.putAll(entry.getKey(), entry.getValue()); | |
| } | |
| return multimap; | |
| } | |
| /** | |
| * Creates an Immutable Guava multimap using the input map. | |
| */ | |
| public static <K, V> ImmutableMultimap<K, V> createImmutableMultiMap(Map<K, ? extends Iterable<V>> input) { | |
| ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.builder(); | |
| for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) { | |
| builder.putAll(entry.getKey(), entry.getValue()); | |
| } | |
| return builder.build(); | |
| } | |
| public static <K, V> Map<K, Collection<V>> combine(Map<K, Collection<V>> map1, Map<K, Collection<V>> map2) { | |
| return combine(createMultiMap(map1), createMultiMap(map2)).asMap(); | |
| } | |
| public static <K, V> Multimap<K, V> combine(Multimap<K, V> map1, Multimap<K, V> map2) { | |
| ArrayListMultimap<K, V> map = ArrayListMultimap.create(); | |
| map.putAll(map1); | |
| map.putAll(map2); | |
| return map; | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment