org.eclipse.collections.api.RichIterable Maven / Gradle / Ivy
/*
* Copyright (c) 2018 Goldman Sachs and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompany this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.eclipse.collections.api;
import java.util.Collection;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.IntSummaryStatistics;
import java.util.LongSummaryStatistics;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
import org.eclipse.collections.api.bag.Bag;
import org.eclipse.collections.api.bag.MutableBag;
import org.eclipse.collections.api.bag.MutableBagIterable;
import org.eclipse.collections.api.bag.sorted.MutableSortedBag;
import org.eclipse.collections.api.bimap.MutableBiMap;
import org.eclipse.collections.api.block.function.Function;
import org.eclipse.collections.api.block.function.Function0;
import org.eclipse.collections.api.block.function.Function2;
import org.eclipse.collections.api.block.function.primitive.BooleanFunction;
import org.eclipse.collections.api.block.function.primitive.ByteFunction;
import org.eclipse.collections.api.block.function.primitive.CharFunction;
import org.eclipse.collections.api.block.function.primitive.DoubleFunction;
import org.eclipse.collections.api.block.function.primitive.DoubleObjectToDoubleFunction;
import org.eclipse.collections.api.block.function.primitive.FloatFunction;
import org.eclipse.collections.api.block.function.primitive.FloatObjectToFloatFunction;
import org.eclipse.collections.api.block.function.primitive.IntFunction;
import org.eclipse.collections.api.block.function.primitive.IntObjectToIntFunction;
import org.eclipse.collections.api.block.function.primitive.LongFunction;
import org.eclipse.collections.api.block.function.primitive.LongObjectToLongFunction;
import org.eclipse.collections.api.block.function.primitive.ShortFunction;
import org.eclipse.collections.api.block.predicate.Predicate;
import org.eclipse.collections.api.block.predicate.Predicate2;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.block.procedure.Procedure2;
import org.eclipse.collections.api.collection.primitive.MutableBooleanCollection;
import org.eclipse.collections.api.collection.primitive.MutableByteCollection;
import org.eclipse.collections.api.collection.primitive.MutableCharCollection;
import org.eclipse.collections.api.collection.primitive.MutableDoubleCollection;
import org.eclipse.collections.api.collection.primitive.MutableFloatCollection;
import org.eclipse.collections.api.collection.primitive.MutableIntCollection;
import org.eclipse.collections.api.collection.primitive.MutableLongCollection;
import org.eclipse.collections.api.collection.primitive.MutableShortCollection;
import org.eclipse.collections.api.factory.Bags;
import org.eclipse.collections.api.factory.Maps;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.map.MapIterable;
import org.eclipse.collections.api.map.MutableMap;
import org.eclipse.collections.api.map.MutableMapIterable;
import org.eclipse.collections.api.map.primitive.ObjectDoubleMap;
import org.eclipse.collections.api.map.primitive.ObjectLongMap;
import org.eclipse.collections.api.map.sorted.MutableSortedMap;
import org.eclipse.collections.api.multimap.Multimap;
import org.eclipse.collections.api.multimap.MutableMultimap;
import org.eclipse.collections.api.ordered.OrderedIterable;
import org.eclipse.collections.api.partition.PartitionIterable;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.api.set.sorted.MutableSortedSet;
import org.eclipse.collections.api.tuple.Pair;
/**
* RichIterable is an interface which extends the InternalIterable interface with several internal iterator methods, from
* the Smalltalk Collection protocol. These include select, reject, detect, collect, injectInto, anySatisfy,
* allSatisfy. The API also includes converter methods to convert a RichIterable to a List (toList), to a sorted
* List (toSortedList), to a Set (toSet), and to a Map (toMap).
*
* @since 1.0
*/
public interface RichIterable
extends InternalIterable
{
@Override
default void forEach(Procedure super T> procedure)
{
this.each(procedure);
}
/**
* Returns the number of items in this iterable.
*
* @since 1.0
*/
int size();
/**
* Returns true if this iterable has zero items.
*
* @since 1.0
*/
boolean isEmpty();
/**
* The English equivalent of !this.isEmpty()
*
* @since 1.0
*/
default boolean notEmpty()
{
return !this.isEmpty();
}
/**
* Returns any element of an iterable.
*
* @return an element of an iterable.
* @since 10.0
*/
default T getAny()
{
return this.getFirst();
}
/**
* Returns the first element of an iterable. In the case of a List it is the element at the first index. In the
* case of any other Collection, it is the first element that would be returned during an iteration. If the
* iterable is empty, null is returned. If null is a valid element of the container, then a developer would need to
* check to see if the iterable is empty to validate that a null result was not due to the container being empty.
*
* The order of Sets are not guaranteed (except for TreeSets and other Ordered Set implementations), so if you use
* this method, the first element could be any element from the Set.
*
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#getFirst()} instead.
*/
@Deprecated
T getFirst();
/**
* Returns the last element of an iterable. In the case of a List it is the element at the last index. In the case
* of any other Collection, it is the last element that would be returned during an iteration. If the iterable is
* empty, null is returned. If null is a valid element of the container, then a developer would need to check to
* see if the iterable is empty to validate that a null result was not due to the container being empty.
*
* The order of Sets are not guaranteed (except for TreeSets and other Ordered Set implementations), so if you use
* this method, the last element could be any element from the Set.
*
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#getLast()} instead.
*/
@Deprecated
T getLast();
/**
* Returns the element if the iterable has exactly one element. Otherwise, throw {@link IllegalStateException}.
*
* @return an element of an iterable.
* @throws IllegalStateException if iterable is empty or has multiple elements.
* @since 8.0
*/
default T getOnly()
{
if (this.size() == 1)
{
return this.getFirst();
}
throw new IllegalStateException("Size must be 1 but was " + this.size());
}
/**
* Returns true if the iterable has an element which responds true to element.equals(object).
*
* @since 1.0
*/
boolean contains(Object object);
/**
* Returns true if the iterable has an element which responds true to element.equals(value)
* after applying the specified function to the element.
*
* @since 10.3
*/
default boolean containsBy(
Function super T, ? extends V> function,
V value)
{
Objects.requireNonNull(function);
Predicate super T> predicate = null == value
? each -> null == function.valueOf(each)
: each -> value.equals(function.valueOf(each));
return this.anySatisfy(predicate);
}
/**
* Returns true if all elements in source are contained in this collection.
*
* @since 1.0
*/
boolean containsAllIterable(Iterable> source);
/**
* Returns true if all elements in source are contained in this collection.
*
* @see Collection#containsAll(Collection)
* @since 1.0
*/
boolean containsAll(Collection> source);
/**
* Returns true if all elements in the specified var arg array are contained in this collection.
*
* @since 1.0
*/
boolean containsAllArguments(Object... elements);
/**
* Executes the Procedure for each element in the iterable and returns {@code this}.
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Person> tapped =
* people.tap(person -> LOGGER.info(person.getName()));
*
*
* Example using an anonymous inner class:
*
* RichIterable<Person> tapped =
* people.tap(new Procedure<Person>()
* {
* public void value(Person person)
* {
* LOGGER.info(person.getName());
* }
* });
*
*
* @see #each(Procedure)
* @see #forEach(Procedure)
* @since 6.0
*/
RichIterable tap(Procedure super T> procedure);
/**
* The procedure is executed for each element in the iterable.
*
* Example using a Java 8 lambda expression:
*
* people.each(person -> LOGGER.info(person.getName()));
*
*
* Example using an anonymous inner class:
*
* people.each(new Procedure<Person>()
* {
* public void value(Person person)
* {
* LOGGER.info(person.getName());
* }
* });
*
* This method is a variant of {@link InternalIterable#forEach(Procedure)}
* that has a signature conflict with {@link Iterable#forEach(java.util.function.Consumer)}.
*
* @see InternalIterable#forEach(Procedure)
* @see Iterable#forEach(java.util.function.Consumer)
* @since 6.0
*/
@SuppressWarnings("UnnecessaryFullyQualifiedName")
void each(Procedure super T> procedure);
/**
* Returns all elements of the source collection that return true when evaluating the predicate. This method is also
* commonly called filter.
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Person> selected =
* people.select(person -> person.getAddress().getCity().equals("London"));
*
*
* Example using an anonymous inner class:
*
* RichIterable<Person> selected =
* people.select(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.getAddress().getCity().equals("London");
* }
* });
*
*
* @since 1.0
*/
RichIterable select(Predicate super T> predicate);
/**
* Same as the select method with one parameter but uses the specified target collection for the results.
*
* Example using a Java 8 lambda expression:
*
* MutableList<Person> selected =
* people.select(person -> person.person.getLastName().equals("Smith"), Lists.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* MutableList<Person> selected =
* people.select(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.person.getLastName().equals("Smith");
* }
* }, Lists.mutable.empty());
*
*
*
* @param predicate a {@link Predicate} to use as the select criteria
* @param target the Collection to append to for all elements in this {@code RichIterable} that meet select criteria {@code predicate}
* @return {@code target}, which contains appended elements as a result of the select criteria
* @see #select(Predicate)
* @since 1.0
*/
> R select(Predicate super T> predicate, R target);
/**
* Similar to {@link #select(Predicate)}, except with an evaluation parameter for the second generic argument in {@link Predicate2}.
*
* E.g. return a {@link Collection} of Person elements where the person has an age greater than or equal to 18 years
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Person> selected =
* people.selectWith((Person person, Integer age) -> person.getAge()>= age, Integer.valueOf(18));
*
*
* Example using an anonymous inner class:
*
* RichIterable<Person> selected =
* people.selectWith(new Predicate2<Person, Integer>()
* {
* public boolean accept(Person person, Integer age)
* {
* return person.getAge()>= age;
* }
* }, Integer.valueOf(18));
*
*
* @param predicate a {@link Predicate2} to use as the select criteria
* @param parameter a parameter to pass in for evaluation of the second argument {@code P} in {@code predicate}
* @see #select(Predicate)
* @since 5.0
*/
RichIterable selectWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Similar to {@link #select(Predicate, Collection)}, except with an evaluation parameter for the second generic argument in {@link Predicate2}.
*
* E.g. return a {@link Collection} of Person elements where the person has an age greater than or equal to 18 years
*
* Example using a Java 8 lambda expression:
*
* MutableList<Person> selected =
* people.selectWith((Person person, Integer age) -> person.getAge()>= age, Integer.valueOf(18), Lists.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* MutableList<Person> selected =
* people.selectWith(new Predicate2<Person, Integer>()
* {
* public boolean accept(Person person, Integer age)
* {
* return person.getAge()>= age;
* }
* }, Integer.valueOf(18), Lists.mutable.empty());
*
*
* @param predicate a {@link Predicate2} to use as the select criteria
* @param parameter a parameter to pass in for evaluation of the second argument {@code P} in {@code predicate}
* @param targetCollection the Collection to append to for all elements in this {@code RichIterable} that meet select criteria {@code predicate}
* @return {@code targetCollection}, which contains appended elements as a result of the select criteria
* @see #select(Predicate)
* @see #select(Predicate, Collection)
* @since 1.0
*/
> R selectWith(
Predicate2 super T, ? super P> predicate,
P parameter,
R targetCollection);
/**
* Returns all elements of the source collection that return false when evaluating of the predicate. This method is also
* sometimes called filterNot and is the equivalent of calling iterable.select(Predicates.not(predicate)).
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Person> rejected =
* people.reject(person -> person.person.getLastName().equals("Smith"));
*
*
* Example using an anonymous inner class:
*
* RichIterable<Person> rejected =
* people.reject(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.person.getLastName().equals("Smith");
* }
* });
*
*
* @param predicate a {@link Predicate} to use as the reject criteria
* @return a RichIterable that contains elements that cause {@link Predicate#accept(Object)} method to evaluate to false
* @since 1.0
*/
RichIterable reject(Predicate super T> predicate);
/**
* Similar to {@link #reject(Predicate)}, except with an evaluation parameter for the second generic argument in {@link Predicate2}.
*
* E.g. return a {@link Collection} of Person elements where the person has an age greater than or equal to 18 years
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Person> rejected =
* people.rejectWith((Person person, Integer age) -> person.getAge() < age, Integer.valueOf(18));
*
*
* Example using an anonymous inner class:
*
* MutableList<Person> rejected =
* people.rejectWith(new Predicate2<Person, Integer>()
* {
* public boolean accept(Person person, Integer age)
* {
* return person.getAge() < age;
* }
* }, Integer.valueOf(18));
*
*
* @param predicate a {@link Predicate2} to use as the select criteria
* @param parameter a parameter to pass in for evaluation of the second argument {@code P} in {@code predicate}
* @see #select(Predicate)
* @since 5.0
*/
RichIterable rejectWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Same as the reject method with one parameter but uses the specified target collection for the results.
*
* Example using a Java 8 lambda expression:
*
* MutableList<Person> rejected =
* people.reject(person -> person.person.getLastName().equals("Smith"), Lists.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* MutableList<Person> rejected =
* people.reject(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.person.getLastName().equals("Smith");
* }
* }, Lists.mutable.empty());
*
*
* @param predicate a {@link Predicate} to use as the reject criteria
* @param target the Collection to append to for all elements in this {@code RichIterable} that cause {@code Predicate#accept(Object)} method to evaluate to false
* @return {@code target}, which contains appended elements as a result of the reject criteria
* @since 1.0
*/
> R reject(Predicate super T> predicate, R target);
/**
* Similar to {@link #reject(Predicate, Collection)}, except with an evaluation parameter for the second generic argument in {@link Predicate2}.
*
* E.g. return a {@link Collection} of Person elements where the person has an age greater than or equal to 18 years
*
* Example using a Java 8 lambda expression:
*
* MutableList<Person> rejected =
* people.rejectWith((Person person, Integer age) -> person.getAge() < age, Integer.valueOf(18), Lists.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* MutableList<Person> rejected =
* people.rejectWith(new Predicate2<Person, Integer>()
* {
* public boolean accept(Person person, Integer age)
* {
* return person.getAge() < age;
* }
* }, Integer.valueOf(18), Lists.mutable.empty());
*
*
* @param predicate a {@link Predicate2} to use as the reject criteria
* @param parameter a parameter to pass in for evaluation of the second argument {@code P} in {@code predicate}
* @param targetCollection the Collection to append to for all elements in this {@code RichIterable} that cause {@code Predicate#accept(Object)} method to evaluate to false
* @return {@code targetCollection}, which contains appended elements as a result of the reject criteria
* @see #reject(Predicate)
* @see #reject(Predicate, Collection)
* @since 1.0
*/
> R rejectWith(
Predicate2 super T, ? super P> predicate,
P parameter,
R targetCollection);
/**
* Filters a collection into a PartitionedIterable based on the evaluation of the predicate.
*
* Example using a Java 8 lambda expression:
*
* PartitionIterable<Person> newYorkersAndNonNewYorkers =
* people.partition(person -> person.getAddress().getState().getName().equals("New York"));
*
*
* Example using an anonymous inner class:
*
* PartitionIterable<Person> newYorkersAndNonNewYorkers =
* people.partition(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.getAddress().getState().getName().equals("New York");
* }
* });
*
*
* @since 1.0.
*/
PartitionIterable partition(Predicate super T> predicate);
/**
* Filters a collection into a PartitionIterable based on the evaluation of the predicate.
*
* Example using a Java 8 lambda expression:
*
* PartitionIterable<Person> newYorkersAndNonNewYorkers =
* people.partitionWith((Person person, String state) -> person.getAddress().getState().getName().equals(state), "New York");
*
*
* Example using an anonymous inner class:
*
* PartitionIterable<Person> newYorkersAndNonNewYorkers =
* people.partitionWith(new Predicate2<Person, String>()
* {
* public boolean accept(Person person, String state)
* {
* return person.getAddress().getState().getName().equals(state);
* }
* }, "New York");
*
*
* @since 5.0.
*/
PartitionIterable partitionWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns all elements of the source collection that are instances of the Class {@code clazz}.
*
*
* RichIterable<Integer> integers =
* List.mutable.with(new Integer(0), new Long(0L), new Double(0.0)).selectInstancesOf(Integer.class);
*
*
* @since 2.0
*/
RichIterable selectInstancesOf(Class clazz);
/**
* Returns a new collection with the results of applying the specified function on each element of the source
* collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* RichIterable<String> names =
* people.collect(person -> person.getFirstName() + " " + person.getLastName());
*
*
* Example using an anonymous inner class:
*
* RichIterable<String> names =
* people.collect(new Function<Person, String>()
* {
* public String valueOf(Person person)
* {
* return person.getFirstName() + " " + person.getLastName();
* }
* });
*
*
* @since 1.0
*/
RichIterable collect(Function super T, ? extends V> function);
/**
* Same as {@link #collect(Function)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* MutableList<String> names =
* people.collect(person -> person.getFirstName() + " " + person.getLastName(), Lists.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* MutableList<String> names =
* people.collect(new Function<Person, String>()
* {
* public String valueOf(Person person)
* {
* return person.getFirstName() + " " + person.getLastName();
* }
* }, Lists.mutable.empty());
*
*
* @param function a {@link Function} to use as the collect transformation function
* @param target the Collection to append to for all elements in this {@code RichIterable} that meet select criteria {@code function}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @see #collect(Function)
* @since 1.0
*/
> R collect(Function super T, ? extends V> function, R target);
/**
* Returns a new primitive {@code boolean} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* BooleanIterable licenses =
* people.collectBoolean(person -> person.hasDrivingLicense());
*
*
* Example using an anonymous inner class:
*
* BooleanIterable licenses =
* people.collectBoolean(new BooleanFunction<Person>()
* {
* public boolean booleanValueOf(Person person)
* {
* return person.hasDrivingLicense();
* }
* });
*
*
* @since 4.0
*/
BooleanIterable collectBoolean(BooleanFunction super T> booleanFunction);
/**
* Same as {@link #collectBoolean(BooleanFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* BooleanArrayList licenses =
* people.collectBoolean(person -> person.hasDrivingLicense(), new BooleanArrayList());
*
*
* Example using an anonymous inner class:
*
* BooleanArrayList licenses =
* people.collectBoolean(new BooleanFunction<Person>()
* {
* public boolean booleanValueOf(Person person)
* {
* return person.hasDrivingLicense();
* }
* }, new BooleanArrayList());
*
*
* @param booleanFunction a {@link BooleanFunction} to use as the collect transformation function
* @param target the MutableBooleanCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectBoolean(BooleanFunction super T> booleanFunction, R target);
/**
* Returns a new primitive {@code byte} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* ByteIterable bytes =
* people.collectByte(person -> person.getCode());
*
*
* Example using an anonymous inner class:
*
* ByteIterable bytes =
* people.collectByte(new ByteFunction<Person>()
* {
* public byte byteValueOf(Person person)
* {
* return person.getCode();
* }
* });
*
*
* @since 4.0
*/
ByteIterable collectByte(ByteFunction super T> byteFunction);
/**
* Same as {@link #collectByte(ByteFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* ByteArrayList bytes =
* people.collectByte(person -> person.getCode(), new ByteArrayList());
*
*
* Example using an anonymous inner class:
*
* ByteArrayList bytes =
* people.collectByte(new ByteFunction<Person>()
* {
* public byte byteValueOf(Person person)
* {
* return person.getCode();
* }
* }, new ByteArrayList());
*
*
* @param byteFunction a {@link ByteFunction} to use as the collect transformation function
* @param target the MutableByteCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectByte(ByteFunction super T> byteFunction, R target);
/**
* Returns a new primitive {@code char} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* CharIterable chars =
* people.collectChar(person -> person.getMiddleInitial());
*
*
* Example using an anonymous inner class:
*
* CharIterable chars =
* people.collectChar(new CharFunction<Person>()
* {
* public char charValueOf(Person person)
* {
* return person.getMiddleInitial();
* }
* });
*
*
* @since 4.0
*/
CharIterable collectChar(CharFunction super T> charFunction);
/**
* Same as {@link #collectChar(CharFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* CharArrayList chars =
* people.collectChar(person -> person.getMiddleInitial(), new CharArrayList());
*
*
* Example using an anonymous inner class:
*
* CharArrayList chars =
* people.collectChar(new CharFunction<Person>()
* {
* public char charValueOf(Person person)
* {
* return person.getMiddleInitial();
* }
* }, new CharArrayList());
*
*
* @param charFunction a {@link CharFunction} to use as the collect transformation function
* @param target the MutableCharCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectChar(CharFunction super T> charFunction, R target);
/**
* Returns a new primitive {@code double} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* DoubleIterable doubles =
* people.collectDouble(person -> person.getMilesFromNorthPole());
*
*
* Example using an anonymous inner class:
*
* DoubleIterable doubles =
* people.collectDouble(new DoubleFunction<Person>()
* {
* public double doubleValueOf(Person person)
* {
* return person.getMilesFromNorthPole();
* }
* });
*
*
* @since 4.0
*/
DoubleIterable collectDouble(DoubleFunction super T> doubleFunction);
/**
* Same as {@link #collectDouble(DoubleFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* DoubleArrayList doubles =
* people.collectDouble(person -> person.getMilesFromNorthPole(), new DoubleArrayList());
*
*
* Example using an anonymous inner class:
*
* DoubleArrayList doubles =
* people.collectDouble(new DoubleFunction<Person>()
* {
* public double doubleValueOf(Person person)
* {
* return person.getMilesFromNorthPole();
* }
* }, new DoubleArrayList());
*
*
* @param doubleFunction a {@link DoubleFunction} to use as the collect transformation function
* @param target the MutableDoubleCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectDouble(DoubleFunction super T> doubleFunction, R target);
/**
* Returns a new primitive {@code float} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* FloatIterable floats =
* people.collectFloat(person -> person.getHeightInInches());
*
*
* Example using an anonymous inner class:
*
* FloatIterable floats =
* people.collectFloat(new FloatFunction<Person>()
* {
* public float floatValueOf(Person person)
* {
* return person.getHeightInInches();
* }
* });
*
*
* @since 4.0
*/
FloatIterable collectFloat(FloatFunction super T> floatFunction);
/**
* Same as {@link #collectFloat(FloatFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* FloatArrayList floats =
* people.collectFloat(person -> person.getHeightInInches(), new FloatArrayList());
*
*
* Example using an anonymous inner class:
*
* FloatArrayList floats =
* people.collectFloat(new FloatFunction<Person>()
* {
* public float floatValueOf(Person person)
* {
* return person.getHeightInInches();
* }
* }, new FloatArrayList());
*
*
* @param floatFunction a {@link FloatFunction} to use as the collect transformation function
* @param target the MutableFloatCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectFloat(FloatFunction super T> floatFunction, R target);
/**
* Returns a new primitive {@code int} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* IntIterable ints =
* people.collectInt(person -> person.getAge());
*
*
* Example using an anonymous inner class:
*
* IntIterable ints =
* people.collectInt(new IntFunction<Person>()
* {
* public int intValueOf(Person person)
* {
* return person.getAge();
* }
* });
*
*
* @since 4.0
*/
IntIterable collectInt(IntFunction super T> intFunction);
/**
* Same as {@link #collectInt(IntFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* IntArrayList ints =
* people.collectInt(person -> person.getAge(), new IntArrayList());
*
*
* Example using an anonymous inner class:
*
* IntArrayList ints =
* people.collectInt(new IntFunction<Person>()
* {
* public int intValueOf(Person person)
* {
* return person.getAge();
* }
* }, new IntArrayList());
*
*
* @param intFunction a {@link IntFunction} to use as the collect transformation function
* @param target the MutableIntCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectInt(IntFunction super T> intFunction, R target);
/**
* Returns a new primitive {@code long} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* LongIterable longs =
* people.collectLong(person -> person.getGuid());
*
*
* Example using an anonymous inner class:
*
* LongIterable longs =
* people.collectLong(new LongFunction<Person>()
* {
* public long longValueOf(Person person)
* {
* return person.getGuid();
* }
* });
*
*
* @since 4.0
*/
LongIterable collectLong(LongFunction super T> longFunction);
/**
* Same as {@link #collectLong(LongFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* LongArrayList longs =
* people.collectLong(person -> person.getGuid(), new LongArrayList());
*
*
* Example using an anonymous inner class:
*
* LongArrayList longs =
* people.collectLong(new LongFunction<Person>()
* {
* public long longValueOf(Person person)
* {
* return person.getGuid();
* }
* }, new LongArrayList());
*
*
* @param longFunction a {@link LongFunction} to use as the collect transformation function
* @param target the MutableLongCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectLong(LongFunction super T> longFunction, R target);
/**
* Returns a new primitive {@code short} iterable with the results of applying the specified function on each element
* of the source collection. This method is also commonly called transform or map.
*
* Example using a Java 8 lambda expression:
*
* ShortIterable shorts =
* people.collectShort(person -> person.getNumberOfJunkMailItemsReceivedPerMonth());
*
*
* Example using an anonymous inner class:
*
* ShortIterable shorts =
* people.collectShort(new ShortFunction<Person>()
* {
* public short shortValueOf(Person person)
* {
* return person.getNumberOfJunkMailItemsReceivedPerMonth();
* }
* });
*
*
* @since 4.0
*/
ShortIterable collectShort(ShortFunction super T> shortFunction);
/**
* Same as {@link #collectShort(ShortFunction)}, except that the results are gathered into the specified {@code target}
* collection.
*
* Example using a Java 8 lambda expression:
*
* ShortArrayList shorts =
* people.collectShort(person -> person.getNumberOfJunkMailItemsReceivedPerMonth, new ShortArrayList());
*
*
* Example using an anonymous inner class:
*
* ShortArrayList shorts =
* people.collectShort(new ShortFunction<Person>()
* {
* public short shortValueOf(Person person)
* {
* return person.getNumberOfJunkMailItemsReceivedPerMonth;
* }
* }, new ShortArrayList());
*
*
* @param shortFunction a {@link ShortFunction} to use as the collect transformation function
* @param target the MutableShortCollection to append to for all elements in this {@code RichIterable}
* @return {@code target}, which contains appended elements as a result of the collect transformation
* @since 5.0
*/
R collectShort(ShortFunction super T> shortFunction, R target);
/**
* Same as {@link #collect(Function)} with a {@code Function2} and specified parameter which is passed to the block.
*
* Example using a Java 8 lambda expression:
*
* RichIterable<Integer> integers =
* Lists.mutable.with(1, 2, 3).collectWith((each, parameter) -> each + parameter, Integer.valueOf(1));
*
*
* Example using an anonymous inner class:
*
* Function2<Integer, Integer, Integer> addParameterFunction =
* new Function2<Integer, Integer, Integer>()
* {
* public Integer value(Integer each, Integer parameter)
* {
* return each + parameter;
* }
* };
* RichIterable<Integer> integers =
* Lists.mutable.with(1, 2, 3).collectWith(addParameterFunction, Integer.valueOf(1));
*
*
* @param function A {@link Function2} to use as the collect transformation function
* @param parameter A parameter to pass in for evaluation of the second argument {@code P} in {@code function}
* @return A new {@code RichIterable} that contains the transformed elements returned by {@link Function2#value(Object, Object)}
* @see #collect(Function)
* @since 5.0
*/
RichIterable collectWith(Function2 super T, ? super P, ? extends V> function, P parameter);
/**
* Same as collectWith but with a targetCollection parameter to gather the results.
*
* Example using a Java 8 lambda expression:
*
* MutableSet<Integer> integers =
* Lists.mutable.with(1, 2, 3).collectWith((each, parameter) -> each + parameter, Integer.valueOf(1), Sets.mutable.empty());
*
*
* Example using an anonymous inner class:
*
* Function2<Integer, Integer, Integer> addParameterFunction =
* new Function2<Integer, Integer, Integer>()
* {
* public Integer value(final Integer each, final Integer parameter)
* {
* return each + parameter;
* }
* };
* MutableSet<Integer> integers =
* Lists.mutable.with(1, 2, 3).collectWith(addParameterFunction, Integer.valueOf(1), Sets.mutable.empty());
*
*
* @param function a {@link Function2} to use as the collect transformation function
* @param parameter a parameter to pass in for evaluation of the second argument {@code P} in {@code function}
* @param targetCollection the Collection to append to for all elements in this {@code RichIterable} that meet select criteria {@code function}
* @return {@code targetCollection}, which contains appended elements as a result of the collect transformation
* @since 1.0
*/
> R collectWith(
Function2 super T, ? super P, ? extends V> function,
P parameter,
R targetCollection);
/**
* Returns a new collection with the results of applying the specified function on each element of the source
* collection, but only for those elements which return true upon evaluation of the predicate. This is the
* the optimized equivalent of calling iterable.select(predicate).collect(function).
*
* Example using a Java 8 lambda and method reference:
*
* RichIterable<String> strings = Lists.mutable.with(1, 2, 3).collectIf(e -> e != null, Object::toString);
*
*
* Example using Predicates factory:
*
* RichIterable<String> strings = Lists.mutable.with(1, 2, 3).collectIf(Predicates.notNull(), Functions.getToString());
*
*
* @since 1.0
*/
RichIterable collectIf(Predicate super T> predicate, Function super T, ? extends V> function);
/**
* Same as the collectIf method with two parameters but uses the specified target collection for the results.
*
* @param predicate a {@link Predicate} to use as the select criteria
* @param function a {@link Function} to use as the collect transformation function
* @param target the Collection to append to for all elements in this {@code RichIterable} that meet the collect criteria {@code predicate}
* @return {@code targetCollection}, which contains appended elements as a result of the collect criteria and transformation
* @see #collectIf(Predicate, Function)
* @since 1.0
*/
> R collectIf(
Predicate super T> predicate,
Function super T, ? extends V> function,
R target);
/**
* {@code flatCollect} is a special case of {@link #collect(Function)}. With {@code collect}, when the {@link Function} returns
* a collection, the result is a collection of collections. {@code flatCollect} outputs a single "flattened" collection
* instead. This method is commonly called flatMap.
*
* Consider the following example where we have a {@code Person} class, and each {@code Person} has a list of {@code Address} objects. Take the following {@link Function}:
*
* Function<Person, List<Address>> addressFunction = Person::getAddresses;
* RichIterable<Person> people = ...;
*
* Using {@code collect} returns a collection of collections of addresses.
*
* RichIterable<List<Address>> addresses = people.collect(addressFunction);
*
* Using {@code flatCollect} returns a single flattened list of addresses.
*
* RichIterable<Address> addresses = people.flatCollect(addressFunction);
*
*
* @param function The {@link Function} to apply
* @return a new flattened collection produced by applying the given {@code function}
* @since 1.0
*/
RichIterable flatCollect(Function super T, ? extends Iterable> function);
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectByte(Function super T, ? extends ByteIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectChar(Function super T, ? extends CharIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectInt(Function super T, ? extends IntIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectShort(Function super T, ? extends ShortIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectDouble(Function super T, ? extends DoubleIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectFloat(Function super T, ? extends FloatIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectLong(Function super T, ? extends LongIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
default R flatCollectBoolean(Function super T, ? extends BooleanIterable> function, R target)
{
this.forEach(each -> target.addAll(function.valueOf(each)));
return target;
}
/**
* @since 9.2
*/
default RichIterable flatCollectWith(Function2 super T, ? super P, ? extends Iterable> function, P parameter)
{
return this.flatCollect(each -> function.apply(each, parameter));
}
/**
* Same as flatCollect, only the results are collected into the target collection.
*
* @param function The {@link Function} to apply
* @param target The collection into which results should be added.
* @return {@code target}, which will contain a flattened collection of results produced by applying the given {@code function}
* @see #flatCollect(Function)
*/
> R flatCollect(Function super T, ? extends Iterable> function, R target);
/**
* @since 9.2
*/
default > R flatCollectWith(Function2 super T, ? super P, ? extends Iterable> function, P parameter, R target)
{
return this.flatCollect(each -> function.apply(each, parameter), target);
}
/**
* Returns the first element of the iterable for which the predicate evaluates to true or null in the case where no
* element returns true. This method is commonly called find.
*
* Example using a Java 8 lambda expression:
*
* Person person =
* people.detect(person -> person.getFirstName().equals("John") && person.getLastName().equals("Smith"));
*
*
* Example using an anonymous inner class:
*
* Person person =
* people.detect(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.getFirstName().equals("John") && person.getLastName().equals("Smith");
* }
* });
*
*
* @since 1.0
*/
T detect(Predicate super T> predicate);
/**
* Returns the first element that evaluates to true for the specified predicate2 and parameter, or null if none
* evaluate to true.
*
* Example using a Java 8 lambda expression:
*
* Person person =
* people.detectWith((person, fullName) -> person.getFullName().equals(fullName), "John Smith");
*
*
* Example using an anonymous inner class:
*
* Person person =
* people.detectWith(new Predicate2<Person, String>()
* {
* public boolean accept(Person person, String fullName)
* {
* return person.getFullName().equals(fullName);
* }
* }, "John Smith");
*
*
* @since 5.0
*/
T detectWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns the first element of the iterable for which the predicate evaluates to true as an Optional. This method is commonly called find.
*
* Example using a Java 8 lambda expression:
*
* Person person =
* people.detectOptional(person -> person.getFirstName().equals("John") && person.getLastName().equals("Smith"));
*
*
*
* @throws NullPointerException if the element selected is null
* @since 8.0
*/
Optional detectOptional(Predicate super T> predicate);
/**
* Returns the first element that evaluates to true for the specified predicate2 and parameter as an Optional.
*
* Example using a Java 8 lambda expression:
*
* Optional<Person> person =
* people.detectWithOptional((person, fullName) -> person.getFullName().equals(fullName), "John Smith");
*
*
*
* @throws NullPointerException if the element selected is null
* @since 8.0
*/
Optional detectWithOptional(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns the first element of the iterable for which the predicate evaluates to true. If no element matches
* the predicate, then returns the value of applying the specified function.
*
* @since 1.0
*/
default T detectIfNone(Predicate super T> predicate, Function0 extends T> function)
{
T result = this.detect(predicate);
return result == null ? function.value() : result;
}
/**
* Returns the first element of the iterable that evaluates to true for the specified predicate2 and parameter, or
* returns the value of evaluating the specified function.
*
* @since 5.0
*/
T detectWithIfNone(
Predicate2 super T, ? super P> predicate,
P parameter,
Function0 extends T> function);
/**
* Return the total number of elements that answer true to the specified predicate.
*
* Example using a Java 8 lambda expression:
*
* int count =
* people.count(person -> person.getAddress().getState().getName().equals("New York"));
*
*
* Example using an anonymous inner class:
*
* int count =
* people.count(new Predicate<Person>()
* {
* public boolean accept(Person person)
* {
* return person.getAddress().getState().getName().equals("New York");
* }
* });
*
*
* @since 1.0
*/
int count(Predicate super T> predicate);
/**
* Returns the total number of elements that evaluate to true for the specified predicate.
*
* e.g.
* return lastNames.countWith(Predicates2.equal(), "Smith");
*
*/
int countWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns true if the predicate evaluates to true for any element of the iterable.
* Returns false if the iterable is empty, or if no element returned true when evaluating the predicate.
*
* @since 1.0
*/
boolean anySatisfy(Predicate super T> predicate);
/**
* Returns true if the predicate evaluates to true for any element of the collection, or return false.
* Returns false if the collection is empty.
*
* @since 5.0
*/
boolean anySatisfyWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns true if the predicate evaluates to true for every element of the iterable or if the iterable is empty.
* Otherwise, returns false.
*
* @since 1.0
*/
boolean allSatisfy(Predicate super T> predicate);
/**
* Returns true if the predicate evaluates to true for every element of the collection, or returns false.
*
* @since 5.0
*/
boolean allSatisfyWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns true if the predicate evaluates to false for every element of the iterable or if the iterable is empty.
* Otherwise, returns false.
*
* @since 3.0
*/
boolean noneSatisfy(Predicate super T> predicate);
/**
* Returns true if the predicate evaluates to false for every element of the collection, or return false.
* Returns true if the collection is empty.
*
* @since 5.0
*/
boolean noneSatisfyWith(Predicate2 super T, ? super P> predicate, P parameter);
/**
* Returns the final result of evaluating function using each element of the iterable and the previous evaluation
* result as the parameters. The injected value is used for the first parameter of the first evaluation, and the current
* item in the iterable is used as the second parameter. This method is commonly called fold or sometimes reduce.
*
* @since 1.0
*/
IV injectInto(IV injectedValue, Function2 super IV, ? super T, ? extends IV> function);
/**
* Returns the final int result of evaluating function using each element of the iterable and the previous evaluation
* result as the parameters. The injected value is used for the first parameter of the first evaluation, and the current
* item in the iterable is used as the second parameter.
*
* @since 1.0
*/
int injectInto(int injectedValue, IntObjectToIntFunction super T> function);
/**
* Returns the final long result of evaluating function using each element of the iterable and the previous evaluation
* result as the parameters. The injected value is used for the first parameter of the first evaluation, and the current
* item in the iterable is used as the second parameter.
*
* @since 1.0
*/
long injectInto(long injectedValue, LongObjectToLongFunction super T> function);
/**
* Returns the final float result of evaluating function using each element of the iterable and the previous evaluation
* result as the parameters. The injected value is used for the first parameter of the first evaluation, and the current
* item in the iterable is used as the second parameter.
*
* @since 2.0
*/
float injectInto(float injectedValue, FloatObjectToFloatFunction super T> function);
/**
* Returns the final double result of evaluating function using each element of the iterable and the previous evaluation
* result as the parameters. The injected value is used for the first parameter of the first evaluation, and the current
* item in the iterable is used as the second parameter.
*
* @since 1.0
*/
double injectInto(double injectedValue, DoubleObjectToDoubleFunction super T> function);
/**
* Adds all the elements in this iterable to the specific target Collection.
*
* @since 8.0
*/
> R into(R target);
/**
* Converts the collection to a MutableList implementation.
*
* @since 1.0
*/
MutableList toList();
/**
* Converts the collection to a MutableList implementation and sorts it using the natural order of the elements.
*
* @since 1.0
*/
default MutableList toSortedList()
{
return this.toList().sortThis();
}
/**
* Converts the collection to a MutableList implementation and sorts it using the specified comparator.
*
* @since 1.0
*/
default MutableList toSortedList(Comparator super T> comparator)
{
return this.toList().sortThis(comparator);
}
/**
* Converts the collection to a MutableList implementation and sorts it based on the natural order of the
* attribute returned by {@code function}.
*
* @since 1.0
*/
default > MutableList toSortedListBy(Function super T, ? extends V> function)
{
return this.toSortedList(Comparator.comparing(function));
}
/**
* Converts the collection to a MutableSet implementation.
*
* @since 1.0
*/
MutableSet toSet();
/**
* Converts the collection to a MutableSortedSet implementation and sorts it using the natural order of the
* elements.
*
* @since 1.0
*/
MutableSortedSet toSortedSet();
/**
* Converts the collection to a MutableSortedSet implementation and sorts it using the specified comparator.
*
* @since 1.0
*/
MutableSortedSet toSortedSet(Comparator super T> comparator);
/**
* Converts the collection to a MutableSortedSet implementation and sorts it based on the natural order of the
* attribute returned by {@code function}.
*
* @since 1.0
*/
default > MutableSortedSet toSortedSetBy(Function super T, ? extends V> function)
{
return this.toSortedSet(Comparator.comparing(function));
}
/**
* Converts the collection to the default MutableBag implementation.
*
* @since 1.0
*/
MutableBag toBag();
/**
* Converts the collection to a MutableSortedBag implementation and sorts it using the natural order of the
* elements.
*
* @since 6.0
*/
MutableSortedBag toSortedBag();
/**
* Converts the collection to the MutableSortedBag implementation and sorts it using the specified comparator.
*
* @since 6.0
*/
MutableSortedBag toSortedBag(Comparator super T> comparator);
/**
* Converts the collection to a MutableSortedBag implementation and sorts it based on the natural order of the
* attribute returned by {@code function}.
*
* @since 6.0
*/
default > MutableSortedBag toSortedBagBy(Function super T, ? extends V> function)
{
return this.toSortedBag(Comparator.comparing(function));
}
/**
* Converts the collection to a MutableMap implementation using the specified key and value functions.
*
* @since 1.0
*/
MutableMap toMap(
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction);
/**
* Same as {@link #toMap(Function, Function)}, except that the results are gathered into the specified {@code target}
* map.
*
* @since 10.0
*/
default > R toMap(
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction,
R target)
{
this.forEach(each -> target.put(keyFunction.apply(each), valueFunction.apply(each)));
return target;
}
/**
* Converts the collection to a MutableSortedMap implementation using the specified key and value functions
* sorted by the key elements' natural ordering.
*
* @since 1.0
*/
MutableSortedMap toSortedMap(
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction);
/**
* Converts the collection to a MutableSortedMap implementation using the specified key and value functions
* sorted by the given comparator.
*
* @since 1.0
*/
MutableSortedMap toSortedMap(
Comparator super NK> comparator,
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction);
/**
* Converts the collection to a MutableSortedMap implementation using the specified key and value functions
* and sorts it based on the natural order of the attribute returned by {@code sortBy} function.
*/
default , NK, NV> MutableSortedMap toSortedMapBy(
Function super NK, KK> sortBy,
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction)
{
return this.toSortedMap(Comparator.comparing(sortBy), keyFunction, valueFunction);
}
/**
* Converts the collection to a BiMap implementation using the specified key and value functions.
*
* @since 10.0
*/
MutableBiMap toBiMap(
Function super T, ? extends NK> keyFunction,
Function super T, ? extends NV> valueFunction);
/**
* Returns a lazy (deferred) iterable, most likely implemented by calling LazyIterate.adapt(this).
*
* @since 1.0.
*/
LazyIterable asLazy();
/**
* Converts this iterable to an array.
*
* @see Collection#toArray()
* @since 1.0
*/
Object[] toArray();
/**
* Converts this iterable to an array using the specified target array, assuming the target array is as long
* or longer than the iterable.
*
* @see Collection#toArray(Object[])
* @since 1.0
*/
E[] toArray(E[] array);
/**
* Returns the minimum element out of this container based on the comparator.
*
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
T min(Comparator super T> comparator);
/**
* Returns the maximum element out of this container based on the comparator.
*
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
T max(Comparator super T> comparator);
/**
* Returns the minimum element out of this container based on the comparator as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws NullPointerException if the minimum element is null
* @since 8.2
*/
default Optional minOptional(Comparator super T> comparator)
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.min(comparator));
}
/**
* Returns the maximum element out of this container based on the comparator as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws NullPointerException if the maximum element is null
* @since 8.2
*/
default Optional maxOptional(Comparator super T> comparator)
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.max(comparator));
}
/**
* Returns the minimum element out of this container based on the natural order.
*
* @throws ClassCastException if the elements are not {@link Comparable}
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
T min();
/**
* Returns the maximum element out of this container based on the natural order.
*
* @throws ClassCastException if the elements are not {@link Comparable}
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
T max();
/**
* Returns the minimum element out of this container based on the natural order as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws ClassCastException if the elements are not {@link Comparable}
* @throws NullPointerException if the minimum element is null
* @since 8.2
*/
default Optional minOptional()
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.min());
}
/**
* Returns the maximum element out of this container based on the natural order as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws ClassCastException if the elements are not {@link Comparable}
* @throws NullPointerException if the maximum element is null
* @since 8.2
*/
default Optional maxOptional()
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.max());
}
/**
* Returns the minimum elements out of this container based on the natural order of the attribute returned by Function.
*
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
> T minBy(Function super T, ? extends V> function);
/**
* Returns the maximum elements out of this container based on the natural order of the attribute returned by Function.
*
* @throws NoSuchElementException if the RichIterable is empty
* @since 1.0
*/
> T maxBy(Function super T, ? extends V> function);
/**
* Returns the minimum elements out of this container based on the natural order of the attribute returned by Function as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws NullPointerException if the minimum element is null
* @since 8.2
*/
default > Optional minByOptional(Function super T, ? extends V> function)
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.minBy(function));
}
/**
* Returns the maximum elements out of this container based on the natural order of the attribute returned by Function as an Optional.
* If the container is empty {@link Optional#empty()} is returned.
*
* @throws NullPointerException if the maximum element is null
* @since 8.2
*/
default > Optional maxByOptional(Function super T, ? extends V> function)
{
if (this.isEmpty())
{
return Optional.empty();
}
return Optional.of(this.maxBy(function));
}
/**
* Returns the final long result of evaluating function for each element of the iterable and adding the results
* together.
*
* @since 2.0
*/
long sumOfInt(IntFunction super T> function);
/**
* Returns the final double result of evaluating function for each element of the iterable and adding the results
* together. It uses Kahan summation algorithm to reduce numerical error.
*
* @since 2.0
*/
double sumOfFloat(FloatFunction super T> function);
/**
* Returns the final long result of evaluating function for each element of the iterable and adding the results
* together.
*
* @since 2.0
*/
long sumOfLong(LongFunction super T> function);
/**
* Returns the final double result of evaluating function for each element of the iterable and adding the results
* together. It uses Kahan summation algorithm to reduce numerical error.
*
* @since 2.0
*/
double sumOfDouble(DoubleFunction super T> function);
/**
* Returns the result of summarizing the value returned from applying the IntFunction to
* each element of the iterable.
*
*
* IntSummaryStatistics stats =
* Lists.mutable.with(1, 2, 3).summarizeInt(Integer::intValue);
*
*
* @since 8.0
*/
default IntSummaryStatistics summarizeInt(IntFunction super T> function)
{
IntSummaryStatistics stats = new IntSummaryStatistics();
this.each(each -> stats.accept(function.intValueOf(each)));
return stats;
}
/**
* Returns the result of summarizing the value returned from applying the FloatFunction to
* each element of the iterable.
*
*
* DoubleSummaryStatistics stats =
* Lists.mutable.with(1, 2, 3).summarizeFloat(Integer::floatValue);
*
*
* @since 8.0
*/
default DoubleSummaryStatistics summarizeFloat(FloatFunction super T> function)
{
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
this.each(each -> stats.accept(function.floatValueOf(each)));
return stats;
}
/**
* Returns the result of summarizing the value returned from applying the LongFunction to
* each element of the iterable.
*
*
* LongSummaryStatistics stats =
* Lists.mutable.with(1, 2, 3).summarizeLong(Integer::longValue);
*
*
* @since 8.0
*/
default LongSummaryStatistics summarizeLong(LongFunction super T> function)
{
LongSummaryStatistics stats = new LongSummaryStatistics();
this.each(each -> stats.accept(function.longValueOf(each)));
return stats;
}
/**
* Returns the result of summarizing the value returned from applying the DoubleFunction to
* each element of the iterable.
*
*
* DoubleSummaryStatistics stats =
* Lists.mutable.with(1, 2, 3).summarizeDouble(Integer::doubleValue);
*
*
* @since 8.0
*/
default DoubleSummaryStatistics summarizeDouble(DoubleFunction super T> function)
{
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
this.each(each -> stats.accept(function.doubleValueOf(each)));
return stats;
}
/**
* This method produces the equivalent result as {@link Stream#collect(Collector)}.
*
*
* MutableObjectLongMap<Integer> map2 =
* Lists.mutable.with(1, 2, 3, 4, 5).reduceInPlace(Collectors2.sumByInt(i -> Integer.valueOf(i % 2), Integer::intValue));
*
*
* @since 8.0
*/
default R reduceInPlace(Collector super T, A, R> collector)
{
A mutableResult = collector.supplier().get();
BiConsumer accumulator = collector.accumulator();
this.each(each -> accumulator.accept(mutableResult, each));
return collector.finisher().apply(mutableResult);
}
/**
* This method produces the equivalent result as {@link Stream#collect(Supplier, BiConsumer, BiConsumer)}.
* The combiner used in collect is unnecessary in the serial case, so is not included in the API.
*
* @since 8.0
*/
default R reduceInPlace(Supplier supplier, BiConsumer accumulator)
{
R result = supplier.get();
this.each(each -> accumulator.accept(result, each));
return result;
}
/**
* This method produces the equivalent result as {@link Stream#reduce(BinaryOperator)}.
*
* @since 8.0
*/
default Optional reduce(BinaryOperator accumulator)
{
boolean[] seenOne = new boolean[1];
T[] result = (T[]) new Object[1];
this.each(each ->
{
if (seenOne[0])
{
result[0] = accumulator.apply(result[0], each);
}
else
{
seenOne[0] = true;
result[0] = each;
}
});
return seenOne[0] ? Optional.of(result[0]) : Optional.empty();
}
/**
* Groups and sums the values using the two specified functions.
*
* @since 6.0
*/
ObjectLongMap sumByInt(Function super T, ? extends V> groupBy, IntFunction super T> function);
/**
* Groups and sums the values using the two specified functions.
*
* @since 6.0
*/
ObjectDoubleMap sumByFloat(Function super T, ? extends V> groupBy, FloatFunction super T> function);
/**
* Groups and sums the values using the two specified functions.
*
* @since 6.0
*/
ObjectLongMap sumByLong(Function super T, ? extends V> groupBy, LongFunction super T> function);
/**
* Groups and sums the values using the two specified functions.
*
* @since 6.0
*/
ObjectDoubleMap sumByDouble(Function super T, ? extends V> groupBy, DoubleFunction super T> function);
/**
* Returns a string representation of this collection by delegating to {@link #makeString(String)} and defaulting
* the separator parameter to the characters {@code ", "} (comma and space).
*
* @return a string representation of this collection.
* @since 1.0
*/
default String makeString()
{
return this.makeString(", ");
}
/**
* Returns a string representation of this collection by delegating to {@link #makeString(String, String, String)}
* and defaulting the start and end parameters to {@code ""} (the empty String).
*
* @return a string representation of this collection.
* @since 1.0
*/
default String makeString(String separator)
{
return this.makeString("", separator, "");
}
/**
* Returns a string representation of this collection with the elements separated by the specified
* separator and enclosed between the start and end strings.
*
* @return a string representation of this collection.
* @since 1.0
*/
default String makeString(String start, String separator, String end)
{
Appendable stringBuilder = new StringBuilder();
this.appendString(stringBuilder, start, separator, end);
return stringBuilder.toString();
}
/**
* Prints a string representation of this collection onto the given {@code Appendable}. Prints the string returned
* by {@link #makeString()}.
*
* @since 1.0
*/
default void appendString(Appendable appendable)
{
this.appendString(appendable, ", ");
}
/**
* Prints a string representation of this collection onto the given {@code Appendable}. Prints the string returned
* by {@link #makeString(String)}.
*
* @since 1.0
*/
default void appendString(Appendable appendable, String separator)
{
this.appendString(appendable, "", separator, "");
}
/**
* Prints a string representation of this collection onto the given {@code Appendable}. Prints the string returned
* by {@link #makeString(String, String, String)}.
*
* @since 1.0
*/
void appendString(Appendable appendable, String start, String separator, String end);
/**
* For each element of the iterable, the function is evaluated and the results of these evaluations are collected
* into a new multimap, where the transformed value is the key and the original values are added to the same (or similar)
* species of collection as the source iterable.
*
* Example using a Java 8 method reference:
*
* Multimap<String, Person> peopleByLastName =
* people.groupBy(Person::getLastName);
*
*
* Example using an anonymous inner class:
*
* Multimap<String, Person> peopleByLastName =
* people.groupBy(new Function<Person, String>()
* {
* public String valueOf(Person person)
* {
* return person.getLastName();
* }
* });
*
*
* @since 1.0
*/
Multimap groupBy(Function super T, ? extends V> function);
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection.
*
* @since 9.0
*/
default Bag countBy(Function super T, ? extends V> function)
{
return this.countBy(function, Bags.mutable.empty());
}
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection.
*
* @since 9.0
*/
default > R countBy(Function super T, ? extends V> function, R target)
{
return this.collect(function, target);
}
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection with the specified parameter as the second argument.
*
* @since 9.0
*/
default Bag countByWith(Function2 super T, ? super P, ? extends V> function, P parameter)
{
return this.countByWith(function, parameter, Bags.mutable.empty());
}
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection with the specified parameter as the second argument.
*
* @since 9.0
*/
default > R countByWith(Function2 super T, ? super P, ? extends V> function, P parameter, R target)
{
return this.collectWith(function, parameter, target);
}
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection.
*
* @since 10.0.0
*/
default Bag countByEach(Function super T, ? extends Iterable> function)
{
return this.asLazy().flatCollect(function).toBag();
}
/**
* This method will count the number of occurrences of each value calculated by applying the
* function to each element of the collection.
*
* @since 10.0.0
*/
default > R countByEach(Function super T, ? extends Iterable> function, R target)
{
return this.flatCollect(function, target);
}
/**
* Same as {@link #groupBy(Function)}, except that the results are gathered into the specified {@code target}
* multimap.
*
* Example using a Java 8 method reference:
*
* FastListMultimap<String, Person> peopleByLastName =
* people.groupBy(Person::getLastName, new FastListMultimap<String, Person>());
*
*
* Example using an anonymous inner class:
*
* FastListMultimap<String, Person> peopleByLastName =
* people.groupBy(new Function<Person, String>()
* {
* public String valueOf(Person person)
* {
* return person.getLastName();
* }
* }, new FastListMultimap<String, Person>());
*
*
* @since 1.0
*/
> R groupBy(Function super T, ? extends V> function, R target);
/**
* Similar to {@link #groupBy(Function)}, except the result of evaluating function will return a collection of keys
* for each value.
*
* @since 1.0
*/
Multimap groupByEach(Function super T, ? extends Iterable> function);
/**
* Same as {@link #groupByEach(Function)}, except that the results are gathered into the specified {@code target}
* multimap.
*
* @since 1.0
*/
> R groupByEach(
Function super T, ? extends Iterable> function,
R target);
/**
* For each element of the iterable, the function is evaluated and he results of these evaluations are collected
* into a new map, where the transformed value is the key. The generated keys must each be unique, or else an
* exception is thrown.
*
* @throws IllegalStateException if the keys returned by the function are not unique
* @see #groupBy(Function)
* @since 5.0
*/
MapIterable groupByUniqueKey(Function super T, ? extends V> function);
/**
* Same as {@link #groupByUniqueKey(Function)}, except that the results are gathered into the specified {@code target}
* map.
*
* @throws IllegalStateException if the keys returned by the function are not unique
* @see #groupByUniqueKey(Function)
* @since 6.0
*/
> R groupByUniqueKey(
Function super T, ? extends V> function,
R target);
/**
* Returns a string with the elements of this iterable separated by commas with spaces and
* enclosed in square brackets.
*
*
* Assert.assertEquals("[]", Lists.mutable.empty().toString());
* Assert.assertEquals("[1]", Lists.mutable.with(1).toString());
* Assert.assertEquals("[1, 2, 3]", Lists.mutable.with(1, 2, 3).toString());
*
*
* @return a string representation of this RichIterable
* @see java.util.AbstractCollection#toString()
* @since 1.0
*/
@Override
String toString();
/**
* Returns a {@code RichIterable} formed from this {@code RichIterable} and another {@code RichIterable} by
* combining corresponding elements in pairs. If one of the two {@code RichIterable}s is longer than the other, its
* remaining elements are ignored.
*
* @param that The {@code RichIterable} providing the second half of each result pair
* @param the type of the second half of the returned pairs
* @return A new {@code RichIterable} containing pairs consisting of corresponding elements of this {@code
* RichIterable} and that. The length of the returned {@code RichIterable} is the minimum of the lengths of
* this {@code RichIterable} and that.
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#zip(Iterable)} instead.
*/
@Deprecated
RichIterable> zip(Iterable that);
/**
* Same as {@link #zip(Iterable)} but uses {@code target} for output.
*
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#zip(Iterable, Collection)} instead;
*/
@Deprecated
>> R zip(Iterable that, R target);
/**
* Zips this {@code RichIterable} with its indices.
*
* @return A new {@code RichIterable} containing pairs consisting of all elements of this {@code RichIterable}
* paired with their index. Indices start at 0.
* @see #zip(Iterable)
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#zipWithIndex()} instead.
*/
@Deprecated
RichIterable> zipWithIndex();
/**
* Same as {@link #zipWithIndex()} but uses {@code target} for output.
*
* @since 1.0
* @deprecated in 6.0. Use {@link OrderedIterable#zipWithIndex(Collection)} instead.
*/
@Deprecated
>> R zipWithIndex(R target);
/**
* Partitions elements in fixed size chunks.
*
* @param size the number of elements per chunk
* @return A {@code RichIterable} containing {@code RichIterable}s of size {@code size}, except the last will be
* truncated if the elements don't divide evenly.
* @since 1.0
*/
RichIterable> chunk(int size);
/**
* Applies an aggregate procedure over the iterable grouping results into a Map based on the specific groupBy function.
* Aggregate results are required to be mutable as they will be changed in place by the procedure. A second function
* specifies the initial "zero" aggregate value to work with (i.e. new AtomicInteger(0)).
*
* @since 3.0
*/
default MapIterable aggregateInPlaceBy(
Function super T, ? extends K> groupBy,
Function0 extends V> zeroValueFactory,
Procedure2 super V, ? super T> mutatingAggregator)
{
MutableMap map = Maps.mutable.empty();
this.forEach(each ->
{
K key = groupBy.valueOf(each);
V value = map.getIfAbsentPut(key, zeroValueFactory);
mutatingAggregator.value(value, each);
});
return map;
}
/**
* Applies an aggregate function over the iterable grouping results into a map based on the specific groupBy function.
* Aggregate results are allowed to be immutable as they will be replaced in place in the map. A second function
* specifies the initial "zero" aggregate value to work with (i.e. Integer.valueOf(0)).
*
* @since 3.0
*/
default MapIterable aggregateBy(
Function super T, ? extends K> groupBy,
Function0 extends V> zeroValueFactory,
Function2 super V, ? super T, ? extends V> nonMutatingAggregator)
{
return this.aggregateBy(
groupBy,
zeroValueFactory,
nonMutatingAggregator,
Maps.mutable.empty());
}
/**
* Applies an aggregate function over the iterable grouping results into the target map based on the specific
* groupBy function. Aggregate results are allowed to be immutable as they will be replaced in place in the map. A
* second function specifies the initial "zero" aggregate value to work with (i.e. Integer.valueOf(0)).
*
* @since 10.3
*/
default > R aggregateBy(
Function super T, ? extends K> groupBy,
Function0 extends V> zeroValueFactory,
Function2 super V, ? super T, ? extends V> nonMutatingAggregator,
R target)
{
this.forEach(each ->
{
K key = groupBy.valueOf(each);
target.updateValueWith(key, zeroValueFactory, nonMutatingAggregator, each);
});
return target;
}
/**
* Applies a groupBy function over the iterable, followed by a collect function.
*
* @param groupByFunction a {@link Function} to use as the groupBy transformation function
* @param collectFunction a {@link Function} to use as the collect transformation function
*
* @return The {@code target} collection where the key is the transformed result from applying the groupBy function
* and the value is the transformed result from applying the collect function.
*
* @see #groupBy(Function)
* @see Multimap#collectValues(Function)
*
* @since 10.1.0
*/
default > R groupByAndCollect(
Function super T, ? extends K> groupByFunction,
Function super T, ? extends V> collectFunction,
R target)
{
this.forEach(each -> target.put(groupByFunction.apply(each), collectFunction.apply(each)));
return target;
}
}