de.flapdoodle.guava.Transformations.java Source code

Java tutorial

Introduction

Here is the source code for de.flapdoodle.guava.Transformations.java

Source

/**
 * Copyright (C) 2013
 *   Michael Mosmann <michael@mosmann.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.flapdoodle.guava;

import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ForwardingIterator;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import de.flapdoodle.guava.functions.NoTransformation;
import de.flapdoodle.guava.functions.ValueToCollection;
import java.util.Iterator;

public abstract class Transformations {

    private Transformations() {
        // no instance
    }

    public static <T> Collection<T> emptyIfNull(Collection<T> source) {
        return Types.defaultIfNull(source, Collections.<T>emptyList());
    }

    public static <S, D, C extends Collection<? extends D>> ImmutableList<? extends D> flatmap(
            Collection<? extends S> source, Function<? super S, C> transformation) {
        return Folds.foldLeft(source, Folds.asListFold(transformation), ImmutableList.<D>of());
    }

    public static <S, D, C extends Iterable<? extends D>> Iterable<? extends D> flatmap(
            Iterable<? extends S> source, Function<? super S, C> transformation) {
        //Folds.foldLeft(source, Folds.asIterableFold(transformation), ImmutableList.<D> of());
        return FluentIterable.from(source).transformAndConcat(transformation);
    }

    public static <T> ImmutableList<? extends T> flatmap(
            Collection<? extends Collection<? extends T>> collections) {
        return flatmap(collections, new Function<Collection<? extends T>, Collection<? extends T>>() {

            @Override
            public Collection<? extends T> apply(Collection<? extends T> input) {
                return input;
            }
        });
    }

    public static <T> ImmutableList<? extends T> flatmap(Collection<? extends T> collection,
            Collection<? extends T> otherCollection, Collection<? extends T>... collections) {
        return flatmap(Varargs.asCollection(collection, otherCollection, collections));
    }

    public static <K, V> Map<K, V> map(Iterable<Pair<K, V>> pairs) {
        return map(pairs, new PairToKey<K>(), new PairToValue<V>());
    }

    public static <K, T> Map<K, T> map(Iterable<T> collection, Function<? super T, K> keytransformation) {
        return map(collection, keytransformation, new NoTransformation<T>());
    }

    public static <K, V, T> Map<K, V> map(Iterable<T> collection, Function<? super T, K> keyTransformation,
            Function<? super T, V> valueTransformation) {
        return map(MapCreators.<K, V>hashMap(), collection, keyTransformation, valueTransformation);
    }

    public static <K, V, T> Map<K, V> map(Iterable<T> collection, Function<? super T, K> keyTransformation,
            Foldleft<? super T, V> valueFold) {
        return map(MapCreators.<K, V>hashMap(), collection, keyTransformation, valueFold);
    }

    public static <K extends Enum<K>, T> EnumMap<K, T> map(Class<K> enumType, Iterable<T> collection,
            Function<? super T, K> keytransformation) {
        return map(enumType, collection, keytransformation, new NoTransformation<T>());
    }

    public static <K extends Enum<K>, V, T> EnumMap<K, V> map(Class<K> enumType, Iterable<T> collection,
            Function<? super T, K> keyTransformation, Function<? super T, V> valueTransformation) {
        return map(MapCreators.<K, V>enumMap(enumType), collection, keyTransformation, valueTransformation);
    }

    public static <K extends Enum<K>, V, T> EnumMap<K, V> map(Class<K> enumType, Iterable<T> collection,
            Function<? super T, K> keyTransformation, Foldleft<? super T, V> valueFold) {
        return map(MapCreators.<K, V>enumMap(enumType), collection, keyTransformation, valueFold);
    }

    private static <K, V, T, M extends Map<K, V>> M map(MapCreator<K, V, M> mapCreator, Iterable<T> collection,
            Function<? super T, K> keyTransformation, Function<? super T, V> valueTransformation) {
        return map(mapCreator, collection, keyTransformation,
                new Folds.ValueFromLeftIllegalFold<T, V>(valueTransformation));
    }

    private static <K, V, T, M extends Map<K, V>> M map(MapCreator<K, V, M> mapCreator, Iterable<T> collection,
            Function<? super T, K> keyTransformation, Foldleft<? super T, V> valueFold) {
        M map = mapCreator.newInstance();
        for (T value : collection) {
            K key = keyTransformation.apply(value);
            map.put(key, valueFold.apply(map.get(key), value));
        }
        return map;
    }

    public static <A, B> Predicate<B> map(final Predicate<A> predicate, final Function<B, A> transformation) {
        return new Predicate<B>() {

            @Override
            public boolean apply(B input) {
                return predicate.apply(transformation.apply(input));
            }
        };
    }

    public static <T> Iterable<T> firstOf(Iterable<T> collections, int items) {
        Preconditions.checkArgument(items > 0, "items must be bigger then 0");
        //   return Lists.newArrayList(collections).subList(0, Math.min(collections.size(), items));
        return FluentIterable.from(collections).limit(items);
    }

    public static <T> Collection<T> firstOf(Collection<T> collections, int items) {
        Preconditions.checkArgument(items > 0, "items must be bigger then 0");
        return Lists.newArrayList(firstOf((Iterable<T>) collections, items));
    }

    public static <T> Optional<T> firstOf(Collection<T> collections) {
        if (collections.isEmpty()) {
            return Optional.absent();
        }
        return Optional.of(collections.iterator().next());
    }

    public static <T> Partition<T> partition(Collection<T> collection, Predicate<? super T> filter) {
        return new Partition<T>(Collections2.filter(collection, filter),
                Collections2.filter(collection, Predicates.not(filter)));
    }

    public static <T> Partition<T> split(Collection<T> source, int index) {
        List<T> asList = ImmutableList.copyOf(source);
        Preconditions.checkArgument(index >= 0, "index < 0");
        Preconditions.checkArgument(index <= asList.size(), "index > size");
        return new Partition<T>(asList.subList(0, index), asList.subList(index, asList.size()));
    }

    public static <A, B> ImmutableList<Pair<A, B>> zip(Iterable<A> a, Iterable<B> b) {
        return zip(a.iterator(), b.iterator());
    }

    public static <A, B> ImmutableList<Pair<A, B>> zip(Iterator<A> a, Iterator<B> b) {
        Preconditions.checkNotNull(a, "a is null");
        Preconditions.checkNotNull(b, "b is null");

        final ImmutableList.Builder<Pair<A, B>> builder = ImmutableList.<Pair<A, B>>builder();
        int pos = 0;
        boolean done = false;
        do {
            boolean aNext = a.hasNext();
            boolean bNext = b.hasNext();
            if (aNext && bNext) {
                builder.add(new Pair<A, B>(a.next(), b.next()));
                pos++;
            } else {
                if ((aNext) || (bNext)) {
                    throw new IndexOutOfBoundsException(
                            "no element in " + (aNext ? "a" : "b") + " found at " + pos);
                }
                done = true;
            }
        } while (!done);
        return builder.build();
    }

    public static <V> Function<V, V> noop() {
        return new NoTransformation<V>();
    }

    public static <V> Function<V, Collection<? extends V>> asCollection() {
        return new ValueToCollection<V>();
    }

    public static <S, D> Function<S, Collection<? extends D>> asCollection(Function<S, D> transformation) {
        return Functions.compose(new ValueToCollection<D>(), transformation);
    }

    private static class PairToKey<K> implements Function<Pair<K, ?>, K> {

        @Override
        public K apply(Pair<K, ?> input) {
            return input.a();
        }
    }

    private static class PairToValue<V> implements Function<Pair<?, V>, V> {

        @Override
        public V apply(Pair<?, V> input) {
            return input.b();
        }
    }
}