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

com.jongsoft.lang.collection.Traversable Maven / Gradle / Ivy

The newest version!
package com.jongsoft.lang.collection;

import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import com.jongsoft.lang.Control;
import com.jongsoft.lang.Value;
import com.jongsoft.lang.collection.support.Collections;
import com.jongsoft.lang.collection.tuple.Pair;
import com.jongsoft.lang.control.Optional;

public interface Traversable extends Value, Foldable {

    Traversable filter(Predicate predicate);

    /**
     * Find the first match in the elements using the provided {@link Predicate}.
     * The returned {@linkplain Optional} is {@code null} safe and will either contain the element or be an empty {@link Optional}.
     * 

Example:

*
{@code // the result will be an Optional with the value 2
     *    int firstMatch = Collection(1, 2, 3, 4)
     *          .first(i -> i % 2 == 0);}
* * @param predicate the predicate to use * @return the first match found * @throws NullPointerException in case that the predicate is null */ Optional first(Predicate predicate); @Override Iterator iterator(); /** * Find the last match in the Iterator using the provided {@link Predicate}. * The returned {@linkplain Optional} is {@code null} safe and will either contain the element or be an empty {@link Optional}. *

Example:

*
{@code // the result will be an Optional with the value 4
     *    int firstMatch = Collection(1, 2, 3, 4)
     *          .last(i -> i % 2 == 0);}
* * @param predicate the predicate to use * @return the last match found * @throws NullPointerException in case that the predicate is null */ Optional last(Predicate predicate); Traversable map(Function mapper); /** * Returns either {@code this} if it is non empty, otherwise will return the provided {@code other}. * * @since 1.0.0 * @param other the alternative * @return this {@code Traversable} if non empty, or {@code other} */ Traversable orElse(Iterable other); /** * Returns either {@code this} if it is non empty, otherwise the provided supplier is evaluated and returned. * * @since 1.0.0 * @param supplier the supplier to generate the other * @return this (@code Traversable} if non empty, otherwise other */ Traversable orElse(Supplier> supplier); /** * Return a list that removes all elements that match the {@code predicate} provided. * * @param predicate the predicate to use * @return the elements that do not match the {@code predicate} * @throws NullPointerException in case {@code predicate} is null */ Traversable reject(Predicate predicate); /** * Calculates the sum of this elements. Supported component types are {@code Byte}, {@code Double}, {@code Float}, * {@code Integer}, {@code Long}, {@code Short}, {@code BigInteger} and {@code BigDecimal}. *

* Examples: *

{@code
     * API.List().sum()                          // = Optional()
     * API.List(1, 2, 3).sum()                   // = Optional(6.0)
     * API.List(1.0, 10e100, 2.0, -10e100).sum() // = Optional(3.0)
     * API.List(1.0, Double.NaN).sum()           // = NaN
     * API.List("apple", "pear").sum()           // throws an exception
     * }
* * @since 1.0.0 * @return {@code Optional(sum)}, or {@code Optional()} if no elements are present * @throws ClassCastException if the elements are not numeric */ default Optional sum() { Pair summation = Collections.neumaierSum(this, t -> ((Number) t).doubleValue()); return summation.getFirst() == 0 ? Control.Option() : Control.Option(summation.getSecond()); } /** * Compute the smallest value in the set, based upon the {@link Comparable#compareTo(Object)} operation. Note * all elements in the set must implement this method. *

* Examples: *

{@code
     * API.List().min()                          // = Optional()
     * API.List(1, 2, 3).min()                   // = Optional(1)
     * API.List(1.0, 10e100, 2.0, -10e100).min() // = Optional(1)
     * API.List("apple", "pear").min()           // = Optional("apple")
     * }
* * @since 1.1.4 * @return the smallest value * @throws ClassCastException in case one or more elements does not implement the {@link Comparable} interface. */ default Optional min() { return Collections.compareGreatestSmallest(this, false); } /** * Compute the largest value in the set, based upon the {@link Comparable#compareTo(Object)} operation. Note * all elements in the set must implement this method. * * @since 1.1.4 * @return the maximum value * @throws ClassCastException in case one or more elements does not implement the {@link Comparable} interface. */ default Optional max() { return Collections.compareGreatestSmallest(this, true); } /** * Calculates the average of this elements, assuming that the element type is {@link Number}. * * Since we do not know if the component type {@code T} is of type {@code Number}, the * {@code average()} call might throw at runtime (see examples below). *

* Examples *

{@code
     * API.List().average()                          // = Optional()
     * API.List(1, 2, 3).average()                   // = Optional(2.0)
     * API.List(1.0, 10e100, 2.0, -10e100).average() // = Optional(0.75)
     * API.List(1.0, Double.NaN).average()           // = NaN
     * API.List("apple", "pear").average()           // throws an exception
     * }
* * @since 1.0.0 * @return {@code Optional(average), or {@code Optional()} if no elements are present} * @throws ClassCastException if the elements are not numeric */ default Optional average() { Pair summation = Collections.neumaierSum(this, t -> ((Number) t).doubleValue()); return summation.getFirst() == 0 ? Control.Option() : Control.Option(summation.getSecond() / summation.getFirst()); } }