All Downloads are FREE. Search and download functionalities are using the official Maven repository.

almost.functional.utils.Iterables Maven / Gradle / Ivy

Go to download

Almost Functional is very low impact functional classes inspired by guava, jdk 1.8 and various others.

There is a newer version: 1.8
Show newest version
/*
 * Copyright (c) 2013-2014, [email protected]
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with or
 * without fee is hereby granted, provided that the above copyright notice and this permission
 * notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOFTWARE.
 */

package almost.functional.utils;

import almost.functional.*;

import java.util.Enumeration;
import java.util.Iterator;

import static almost.functional.Optional.of;
import static almost.functional.utils.Preconditions.checkNotNull;

/**
 * Utility operations on an iterable.
 */
public final class Iterables {

	private Iterables() {}

    /**
	 * Accept a consumer for each element of an iterable.
	 * @param i the iterable
	 * @param c the consumer to accept for each element
	 * @param  the type of the iterable and consumer
	 */
	public static  void forEach(Iterable i, final Consumer c) {
		checkNotNull(i, "forEach must have a valid iterable");
		checkNotNull(c, "forEach must have a valid consumer");

		for (T t : i) {
			c.accept(t);
		}
	}

	/**
	 * Perform a reduction of an iterable, using an initial value, and a two argument function. The function
	 * is applied to each element using the last result as the first argument and the element as the second.
	 * @param i the iterable.
	 * @param initial the initial value of the first argument.
	 * @param accumulator the two argument function.
	 * @param  type of the iterable elements and accumulator's second argument
	 * @param  type returned by reduce, the accumulator and it's first argument
	 * @return the final result of the function.
	 * @since 1.5
	 */
	public static  R reduce(Iterable i, final R initial, final BiFunction accumulator) {
		checkNotNull(i, "reduce must have a non null iterable");
		checkNotNull(accumulator, "reduce must have a non null function");

		R ret = initial;
		for (T r : i) {
			ret = accumulator.apply(ret, r);
		}
		return ret;
	}

	/**
	 * Apply a predicate to an iterable, returning an optional of the first element where the predicate is true,
	 * or empty if no true is found.
	 * @param iterable the iterable to traverse
	 * @param predicate the predicate to test
	 * @param  they type of the iterable and predicate
	 * @return an optional of the first element where the predicate is true, or empty if no true is found.
	 */
	public static  Optional find(Iterable iterable, Predicate predicate) {
		checkNotNull(iterable, "iterable may not be null");
		checkNotNull(predicate, "the predicate may not be null");
		for (T t : iterable) {
			if (predicate.test(t)) {
				return of(t);
			}
		}
		return Optional.empty();
	}

	/**
	 * Determine if any element of an iterable matches a given predicate.
	 * @param iterable the iterable to traverse
	 * @param predicate the predicate to test
	 * @param  the type of the iterable and predicate
	 * @return true if any element matches the predicate, otherwise false.
	 */
	public static  boolean any(Iterable iterable, Predicate predicate) {
		return find(iterable, predicate).isPresent();
	}

	/**
	 * Does an iterable contain a value as determined by Object.isEqual(Object, Object).
	 * @param iterable the iterable
	 * @param value the value
	 * @param  the type of the iterable and object
	 * @return true if iterable contain a value as determined by Object.isEqual(Object, Object).
	 */
	public static  boolean contains(Iterable iterable, T value) {
		return any(iterable, Predicates.isEqual(value));
	}

	/**
	 * Create an iterable that maps an existing iterable to a new one by applying a function to each of it's elements.
	 * @param fromIterable the iterable to be transformed
	 * @param function the function to apply to the elements
	 * @param  the type of the original elements, and the argument to the function
	 * @param  the type of the resulting iterable, and the result of the function
	 * @return an iterable that transforms an existing iterable by applying a function to each or it's elements.
	 */
	public static  Iterable map(final Iterable fromIterable, final Function function) {
		checkNotNull(fromIterable, "iterable must be non null");
		checkNotNull(function, "map function must be non null");
		return new Iterable() {
			@Override
			public Iterator iterator() {
				final Iterator fromIterator = fromIterable.iterator();
				return new ImmutableIterator() {
					@Override
					public boolean hasNext() {
						return fromIterator.hasNext();
					}

					@Override
					public T next() {
						return function.apply(fromIterator.next());
					}
				};
			}
		};
	}

    /**
     * Create an iterable that filters an existing iterable based on a predicate.
     * @param fromIterable Iterable being filtered
     * @param predicate the predicate to base inclusion upon, true cases are included, false excluded
     * @param  the type of the elements
     * @return iterable of filtered elements
     */
    public static  Iterable filter(final Iterable fromIterable, final Predicate predicate) {
        checkNotNull(fromIterable, "iterable must be non null");
        checkNotNull(predicate, "predicate must be non null");
	    return new SupplierIterable(new Supplier>() {
			private Iterator fromIterator = fromIterable.iterator();
			public Optional get() {
				while (fromIterator.hasNext()) {
					T value = fromIterator.next();
					if (predicate.test(value)) {
						return of(value);
					}
				}
				return Optional.empty();
			}
		});
    }

    /**
     * Convert an enumeration to an iterator.
     * @param enumeration  the enumeration to make into an Iterator
     * @param  type of the enumeration
     * @throws java.lang.NullPointerException if enumeration is null
     * @return An Iterable
     */
    public static  Iterable iterable(final Enumeration enumeration) {
        checkNotNull(enumeration, "Can not create an Iterable from a null enumeration");
        return new Iterable() {
            public Iterator iterator() {
                return new ImmutableIterator() {
                    public boolean hasNext() {
                        return enumeration.hasMoreElements();
                    }
                    public E next() {
                        return enumeration.nextElement();
                    }
                };
            }
        };
    }

    /**
     * Return an optional of an element from a specified position in an iterable. If the position is out of bounds
     * an empty optional is returned. Positions start at 0.
     * @since 1.7
     * @param iterable the iterable
     * @param position the position
     * @param  the type of the elements
     * @return an optional from the given position, or empty if out of bounds
     */
    public static  Optional get(final Iterable iterable, int position) {
        checkNotNull(iterable, "Get requires an iterable");
        if (position < 0) {
            return Optional.empty();
        }

        int index = 0;
        for (E anIterable : iterable) {
            if (index == position) {
                return of(anIterable);
            }
            index++;
        }

        return Optional.empty();
    }

    /**
     * Return the last element of an iterable, or empty if the iterable is element.
     * @param iterable the iterable
     * @param  type of the iterable elements
     * @return Optional of the last element, or empty if nothing in the iterable
     */
    public static  Optional last(final Iterable iterable) {
        checkNotNull(iterable, "last requires a non null iterable");
        Iterator iterator = iterable.iterator();
        if (!iterator.hasNext()) {
            return Optional.empty();
        }

        E element;
        do {
            element = iterator.next();
        } while (iterator.hasNext());

        return Optional.of(element);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy