org.jamocha.util.Lambdas.java Source code

Java tutorial

Introduction

Here is the source code for org.jamocha.util.Lambdas.java

Source

/*
 * Copyright 2002-2016 The Jamocha Team
 *
 *
 * 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.jamocha.org/
 *
 * 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 org.jamocha.util;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.experimental.UtilityClass;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.stream.Collectors.*;

/**
 * @author Fabian Ohler <fabian.ohler1@rwth-aachen.de>
 */
@UtilityClass
public class Lambdas {

    /* composition with generic return type */

    public static <A, B, C> Function<? super A, ? extends C> compose(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b) {
        return a.andThen(b);
    }

    public static <A, B, C, D> Function<? super A, ? extends D> compose(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c) {
        return compose(compose(a, b), c);
    }

    public static <A, B, C, D, E> Function<? super A, ? extends E> compose(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final Function<? super D, ? extends E> d) {
        return compose(compose(a, b, c), d);
    }

    public static <A, B, C, D, E, F> Function<? super A, ? extends F> compose(
            final Function<? super A, ? extends B> a, final Function<? super B, ? extends C> b,
            final Function<? super C, ? extends D> c, final Function<? super D, ? extends E> d,
            final Function<? super E, ? extends F> e) {
        return compose(compose(a, b, c, d), e);
    }

    /* composition with return type int */

    public static <A, B> ToIntFunction<? super A> composeToInt(final Function<? super A, ? extends B> a,
            final ToIntFunction<? super B> b) {
        return t -> b.applyAsInt(a.apply(t));
    }

    public static <A, B, C> ToIntFunction<? super A> composeToInt(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final ToIntFunction<? super C> c) {
        return composeToInt(compose(a, b), c);
    }

    public static <A, B, C, D> ToIntFunction<? super A> composeToInt(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final ToIntFunction<? super D> d) {
        return composeToInt(compose(a, b, c), d);
    }

    public static <A, B, C, D, E> ToIntFunction<? super A> composeToInt(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final Function<? super D, ? extends E> d, final ToIntFunction<? super E> e) {
        return composeToInt(compose(a, b, c, d), e);
    }

    /* composition with return type double */

    public static <A, B> ToDoubleFunction<? super A> composeToDouble(final Function<? super A, ? extends B> a,
            final ToDoubleFunction<? super B> b) {
        return t -> b.applyAsDouble(a.apply(t));
    }

    public static <A, B, C> ToDoubleFunction<? super A> composeToDouble(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final ToDoubleFunction<? super C> c) {
        return composeToDouble(compose(a, b), c);
    }

    public static <A, B, C, D> ToDoubleFunction<? super A> composeToDouble(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final ToDoubleFunction<? super D> d) {
        return composeToDouble(compose(a, b, c), d);
    }

    public static <A, B, C, D, E> ToDoubleFunction<? super A> composeToDouble(
            final Function<? super A, ? extends B> a, final Function<? super B, ? extends C> b,
            final Function<? super C, ? extends D> c, final Function<? super D, ? extends E> d,
            final ToDoubleFunction<? super E> e) {
        return composeToDouble(compose(a, b, c, d), e);
    }

    /* composition with return type long */

    public static <A, B> ToLongFunction<? super A> composeToLong(final Function<? super A, ? extends B> a,
            final ToLongFunction<? super B> b) {
        return t -> b.applyAsLong(a.apply(t));
    }

    public static <A, B, C> ToLongFunction<? super A> composeToLong(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final ToLongFunction<? super C> c) {
        return composeToLong(compose(a, b), c);
    }

    public static <A, B, C, D> ToLongFunction<? super A> composeToLong(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final ToLongFunction<? super D> d) {
        return composeToLong(compose(a, b, c), d);
    }

    public static <A, B, C, D, E> ToLongFunction<? super A> composeToLong(final Function<? super A, ? extends B> a,
            final Function<? super B, ? extends C> b, final Function<? super C, ? extends D> c,
            final Function<? super D, ? extends E> d, final ToLongFunction<? super E> e) {
        return composeToLong(compose(a, b, c, d), e);
    }

    /* predicate negation */

    public static <A> Predicate<? super A> negate(final Predicate<? super A> p) {
        return p.negate();
    }

    /* computeIfAbsent helpers */

    public static <A, B> Function<A, HashSet<B>> newHashSet() {
        return x -> new HashSet<B>();
    }

    public static <A, B> Function<A, LinkedHashSet<B>> newLinkedHashSet() {
        return x -> new LinkedHashSet<B>();
    }

    public static <A, B> Function<A, Set<B>> newIdentityHashSet() {
        return x -> Collections.newSetFromMap(new IdentityHashMap<>());
    }

    public static <A, B, C> Function<A, HashMap<B, C>> newHashMap() {
        return x -> new HashMap<B, C>();
    }

    public static <A, B, C> Function<A, LinkedHashMap<B, C>> newLinkedHashMap() {
        return x -> new LinkedHashMap<B, C>();
    }

    public static <A, B, C> Function<A, IdentityHashMap<B, C>> newIdentityHashMap() {
        return x -> new IdentityHashMap<B, C>();
    }

    public static <A, B> Function<A, TreeSet<B>> newTreeSet() {
        return x -> new TreeSet<B>();
    }

    public static <A, B, C> Function<A, TreeMap<B, C>> newTreeMap() {
        return x -> new TreeMap<B, C>();
    }

    public static <A, B> Function<? super A, ? extends ArrayList<B>> newArrayList() {
        return x -> new ArrayList<B>();
    }

    /*
    * computeIfAbsentHelpers using the value
    */

    public static <A> Function<A, Set<A>> toSingleton() {
        return x -> Collections.singleton(x);
    }

    public static <A> Function<A, List<A>> toSingletonList() {
        return x -> Collections.singletonList(x);
    }

    public static <A, B> BiFunction<A, B, Map<A, B>> toSingletonMap() {
        return (a, b) -> Collections.singletonMap(a, b);
    }

    /*
    * collector helpers
    */

    public static <A> Collector<A, ?, Set<A>> toIdentityHashSet() {
        return toCollection(Sets::newIdentityHashSet);
    }

    public static <A> Collector<A, ?, HashSet<A>> toHashSet() {
        return toCollection(Sets::newHashSet);
    }

    public static <A extends Comparable<A>> Collector<A, ?, TreeSet<A>> toTreeSet() {
        return toCollection(Sets::newTreeSet);
    }

    public static <A> Collector<A, ?, ArrayList<A>> toArrayList() {
        return toCollection(Lists::newArrayList);
    }

    public static <A> Collector<A, ?, ImmutableList<A>> toImmutableList() {
        return Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf);
    }

    public static <A> Collector<A, ?, LinkedList<A>> toLinkedList() {
        return toCollection(Lists::newLinkedList);
    }

    /*
    * iterable to stream
    */

    public static <T> Stream<T> stream(final Iterable<T> iterable) {
        return StreamSupport.stream(iterable.spliterator(), false);
    }

    /*
    * stream as iterable
    */
    public static <T> Iterable<T> iterable(final Stream<T> stream) {
        return stream::iterator;
    }

    public static <T> Optional<T> or(final Optional<T> first, final Optional<T> second) {
        return first.isPresent() ? first : second;
    }

    public static <T> Set<T> newIdentityHashSet(final Iterable<T> elements) {
        final Set<T> newIdentityHashSet = Sets.newIdentityHashSet();
        Iterables.addAll(newIdentityHashSet, elements);
        return newIdentityHashSet;
    }

    public static <T, K> Collector<T, ?, ArrayList<ArrayList<T>>> groupingIntoListOfLists(
            final Function<? super T, ? extends K> classifier) {
        final Collector<T, ?, Map<K, ArrayList<T>>> groupingBy = groupingBy(classifier, toArrayList());
        return Collectors.collectingAndThen(groupingBy, map -> new ArrayList<>(map.values()));
    }

    public static <T, K> Collector<T, ?, ArrayList<Set<T>>> groupingIntoListOfSets(
            final Function<? super T, ? extends K> classifier) {
        final Collector<T, ?, Map<K, Set<T>>> groupingBy = groupingBy(classifier, toSet());
        return Collectors.collectingAndThen(groupingBy, map -> new ArrayList<>(map.values()));
    }
}