Advertisement
dalexiuc

Stuff Guava is Missing

Apr 3rd, 2012
1,445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.04 KB | None | 0 0
  1. import static com.google.common.base.Optional.of;
  2. import static com.google.common.collect.Iterables.concat;
  3. import static com.google.common.collect.Iterables.filter;
  4. import static com.google.common.collect.Iterables.isEmpty;
  5. import static com.google.common.collect.Iterables.transform;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.Comparator;
  9. import com.google.common.base.Function;
  10. import com.google.common.base.Optional;
  11. import com.google.common.base.Predicate;
  12. import com.google.common.base.Predicates;
  13. import com.google.common.collect.ImmutableSortedSet;
  14. import com.google.common.collect.Lists;
  15. import com.google.common.collect.Multimaps;
  16. import com.google.common.collect.Sets;
  17. import edu.umd.cs.findbugs.annotations.NonNull;
  18.  
  19.  
  20. /**
  21.  * A Bunch of generic collection stuff that really should have been in Guava.
  22.  */
  23. public class CollectionUtil {
  24.  
  25.   private CollectionUtil() {
  26.   }
  27.  
  28.   /**
  29.    * Flattens a list of lists into a single list.
  30.    * Like flatMap in Scala or bind in Haskell, but restricted to Iterables only thanks to Java's laughable type system.
  31.    */
  32.   public static <A, B> Iterable<B> flatTransform(Iterable<A> i, Function<? super A, ? extends Iterable<B>> f) {
  33.     return concat(transform(i, f));
  34.   }
  35.  
  36.   /**
  37.    * Groups elements into a list of lists, with grouping determined by the given function.
  38.    *
  39.    * @param i the elements to group
  40.    * @param f determines the property to group by
  41.    * @return A list of grouped elements.
  42.    */
  43.   public static <A, B> Collection<? extends Collection<? extends A>> group(Iterable<? extends A> i,
  44.       Function<A, B> f) {
  45.     return Multimaps.index(i, f).asMap().values();
  46.   }
  47.  
  48.   /**
  49.    * Left Fold.
  50.    * (a, b, c, d), initial -> f(f(f(f(initial,a), b), c), d)
  51.    * http://en.wikipedia.org/wiki/Fold_(higher-order_function)
  52.    */
  53.   public static <A, B> A fold(final Iterable<? extends B> gen, final A initial,
  54.       final Function2<? super A, ? super B, ? extends A> function) {
  55.     final Iterator<? extends B> it = gen.iterator();
  56.     if (!it.hasNext()) {
  57.       return initial;
  58.     }
  59.     A acc = initial;
  60.     while (it.hasNext()) {
  61.       acc = function.apply(acc, it.next());
  62.     }
  63.     return acc;
  64.   }
  65.  
  66.   /**
  67.    * A transformation function of arity-2 (two arguments) from A and B to C.
  68.    */
  69.   public interface Function2<A, B, C> {  
  70.     C apply(A a, B b);
  71.   }
  72.  
  73.   /**
  74.    * Sums Integers.
  75.    * @param  ints a collection of {@code Integer} objects
  76.    * @return sum of ints
  77.    * @throws NullPointerException if {@code ints} or any of its elements is null
  78.    */
  79.   public static int sum(@NonNull Iterable<Integer> ints) {
  80.     int sum = 0;
  81.     for (int anInt : ints) {
  82.       sum += anInt;
  83.     }
  84.     return sum;
  85.   }
  86.  
  87.  
  88.   /**
  89.    * Returns true if all {@code B}s are equal
  90.    */
  91.   public static <A, B> boolean allEqual(Iterable<A> iterable, Function<A, B> function) {
  92.     return allEqual(transform(iterable, function));
  93.   }
  94.  
  95.   /**
  96.    * Returns true if all elements in the List are equal
  97.    */
  98.   public static boolean allEqual(Iterable<?> iterable) {
  99.     return Sets.newHashSet(iterable).size() < 2;
  100.   }
  101.  
  102.   /**
  103.    * Returns the count of unique {@code A}s according to supplied comparator
  104.    */
  105.   public static <A> int countDistinct(Iterable<A> iterable, Comparator<? super A> comparator) {
  106.     return ImmutableSortedSet.copyOf(comparator, iterable).size();
  107.   }
  108.  
  109.   /**
  110.    * Returns a list with duplicates removed according to the given comparator.
  111.    */
  112.   public static <A> Iterable<A> distinct(Iterable<A> iterable, Comparator<? super A> comparator) {
  113.     return ImmutableSortedSet.copyOf(comparator, iterable);
  114.   }
  115.  
  116.   /**
  117.    * Determines if the given iterable contains no elements.
  118.    */
  119.   public static boolean isNotEmpty(Iterable<?> iterable) {
  120.     return !isEmpty(iterable);
  121.   }
  122.  
  123.   /**
  124.    * Returns true if the predicate holds for at least one of the elements of this iterable, false otherwise
  125.    * (false for the empty list).
  126.    */
  127.   public static <A> boolean exists(Iterable<A> iterable, Predicate<A> predicate) {
  128.     return isNotEmpty(filter(iterable, predicate));
  129.   }
  130.  
  131.   /**
  132.    * Returns true if the iterable has at least one element whose class is {@code type} or a subclass of {@code type}.
  133.    */
  134.   public static boolean exists(Iterable<?> iterable, Class<?> type) {
  135.     return isNotEmpty(filter(iterable, type));
  136.   }
  137.  
  138.   /**
  139.    * Syntactic sugar for Guava's Predicates.in()
  140.    */
  141.   public static <T> Predicate<T> in(T... target) {
  142.     return Predicates.in(Lists.newArrayList(target));
  143.   }
  144.  
  145.   /**
  146.    * Simply returns a new Iterable with each element wrapped in an Optional.
  147.    */
  148.   public static <A> Iterable<Optional<A>> asOptionalList(Iterable<A> iterable) {
  149.     Collection<Optional<A>> list = new ArrayList<Optional<A>>();
  150.     for (A a : iterable) {
  151.       list.add(of(a));
  152.     }
  153.     return list;
  154.   }
  155.  
  156.   /**
  157.    * Creates a Guava multimap using the input map.
  158.    */
  159.   public static <K, V> Multimap<K, V> createMultiMap(Map<K, ? extends Iterable<V>> input) {
  160.     Multimap<K, V> multimap = ArrayListMultimap.create();
  161.     for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) {
  162.       multimap.putAll(entry.getKey(), entry.getValue());
  163.     }
  164.     return multimap;
  165.   }
  166.  
  167.   /**
  168.    * Creates an Immutable Guava multimap using the input map.
  169.    */
  170.   public static <K, V> ImmutableMultimap<K, V> createImmutableMultiMap(Map<K, ? extends Iterable<V>> input) {
  171.     ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.builder();
  172.     for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) {
  173.       builder.putAll(entry.getKey(), entry.getValue());
  174.     }
  175.     return builder.build();
  176.   }
  177.  
  178.   public static <K, V> Map<K, Collection<V>> combine(Map<K, Collection<V>> map1, Map<K, Collection<V>> map2) {
  179.     return combine(createMultiMap(map1), createMultiMap(map2)).asMap();
  180.   }
  181.  
  182.   public static <K, V> Multimap<K, V> combine(Multimap<K, V> map1, Multimap<K, V> map2) {
  183.     ArrayListMultimap<K, V> map = ArrayListMultimap.create();
  184.     map.putAll(map1);
  185.     map.putAll(map2);
  186.     return map;
  187.   }
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement