
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 extends T> 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 extends Iterable extends T>> 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());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy