sirius.kernel.commons.Tuple Maven / Gradle / Ivy
/*
* Made with all the love in the world
* by scireum in Remshalden, Germany
*
* Copyright by scireum GmbH
* http://www.scireum.de - [email protected]
*/
package sirius.kernel.commons;
import com.google.common.base.Objects;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Stream;
/**
* Represents a tuple of two values with two arbitrary types.
*
* If the first type is comparable and should be used to compare the tuples, {@link ComparableTuple} can be used.
*
* @param defines the first type of the tuple
* @param defines the second type of the tuple
* @see Tuple
* @see Comparable
*/
public class Tuple {
private F first;
private S second;
/**
* Creates a tuple with a givens value for first and second
*
* Can be used to specify the generic types for F and S. Otherwise, the create methods can be used.
*
* @param first defines the value to be used for the first component of the tuple
* @param second defines the value to be used for the second component of the tuple
*/
public Tuple(F first, S second) {
super();
this.first = first;
this.second = second;
}
/**
* Creates a new tuple with both values set to null
*
* @param defines the first type of the tuple
* @param defines the second type of the tuple
* @return the newly created tuple
*/
public static Tuple create() {
return new Tuple<>(null, null);
}
/**
* Creates a tuple with a given value for first
*
* @param first defines the value to be used for the first component of the tuple
* @param defines the first type of the tuple
* @param defines the second type of the tuple
* @return the newly created tuple
*/
public static Tuple create(F first) {
return new Tuple<>(first, null);
}
/**
* Creates a tuple with a givens value for first and second
*
* @param first defines the value to be used for the first component of the tuple
* @param second defines the value to be used for the second component of the tuple
* @param defines the first type of the tuple
* @param defines the second type of the tuple
* @return the newly created tuple
*/
public static Tuple create(F first, S second) {
return new Tuple<>(first, second);
}
/**
* Returns the first component of the tuple
*
* @return the first component of the tuple
*/
public F getFirst() {
return first;
}
/**
* Sets the first component of the tuple to the given value.
*
* @param first defines the value to be used as the first component of the tuple
*/
public void setFirst(F first) {
this.first = first;
}
/**
* Returns the second component of the tuple
*
* @return the second component of the tuple
*/
public S getSecond() {
return second;
}
/**
* Sets the second component of the tuple to the given value.
*
* @param second defines the value to be used as the second component of the tuple
*/
public void setSecond(S second) {
this.second = second;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Tuple, ?>)) {
return false;
}
Tuple, ?> other = (Tuple, ?>) obj;
return Objects.equal(first, other.getFirst()) && Objects.equal(second, other.getSecond());
}
@Override
public String toString() {
return first + ": " + second;
}
@Override
public int hashCode() {
return Objects.hashCode(first, second);
}
/**
* Extracts all first components of the given collection of tuples and returns them as list.
*
* @param tuples the collection of tuples to process
* @param the type of the tuples involved
* @param the type of the first elements of the tuples
* @param the type of the second elements of the tuples
* @return a list containing each first component of the collection of given tuples.
*/
public static , K, V> List firsts(@Nonnull Collection tuples) {
List result = new ArrayList<>(tuples.size());
for (Tuple t : tuples) {
result.add(t.getFirst());
}
return result;
}
/**
* Extracts all second components of the given collection of tuples and returns them as list.
*
* @param tuples the collection of tuples to process
* @param the type of the tuples involved
* @param the type of the first elements of the tuples
* @param the type of the second elements of the tuples
* @return a list containing each second component of the collection of given tuples.
*/
public static , K, V> List seconds(@Nonnull Collection tuples) {
List result = new ArrayList<>(tuples.size());
for (Tuple t : tuples) {
result.add(t.getSecond());
}
return result;
}
/**
* Converts a map into a list of tuples.
*
* @param map the map to be converted
* @param the key type of the map and therefore the type of the first component of the tuples
* @param the value type of the map and therefore the type of the second component of the tuples
* @return a list of tuples, containing one tuple per map entry where the first component is the key,
* and the second component is the value of the map entry.
*/
public static List> fromMap(@Nonnull Map map) {
List> result = new ArrayList<>(map.size());
for (Map.Entry e : map.entrySet()) {
result.add(new Tuple<>(e.getKey(), e.getValue()));
}
return result;
}
/**
* Converts a collection of tuples into a map
*
* @param values the collection of tuples to be converted
* @param the key type of the map and therefore the type of the first component of the tuples
* @param the value type of the map and therefore the type of the second component of the tuples
* @return a map containing an entry for each tuple in the collection, where the key is the first component of the
* tuple and the value is the second component of the tuple. If two tuples have equal values as first
* component, the specific map entry will be overridden in the order defined in the given collection.
*/
public static Map toMap(@Nonnull Collection> values) {
Map result = new HashMap<>();
for (Tuple e : values) {
result.put(e.getFirst(), e.getSecond());
}
return result;
}
/**
* Provides a {@link Collector} which can be used to collect a {@link Stream} of tuples into a {@link Map}.
*
* As an example: {@code aStream.collect(Tuple.toMap(HashMap::new, (a, b) -> b))} will transform the
* stream of tuples into a map where a later key value pair will overwrite earlier ones.
*
* @param supplier factory for generating the result map
* @param merger used to decide which value to keep on a key collision
* @param key type of the tuples being processed
* @param value type of the tuples being processed
* @return a Collector which transforms a stream of tuples into a map
* @see #toMap(java.util.function.Supplier)
*/
public static Collector, Map, Map> toMap(Supplier