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

net.yetamine.lang.containers.Tuple3 Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package net.yetamine.lang.containers;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * A rudimentary tuple implementation consisting of three elements.
 *
 * @param 
 *            the type of element #1
 * @param 
 *            the type of element #2
 * @param 
 *            the type of element #3
 */
public final class Tuple3 {

    /** Common shared empty tuple. */
    private static final Tuple3 EMPTY = new Tuple3<>(null, null, null);

    /** Element #1. */
    private final T1 value1;
    /** Element #2. */
    private final T2 value2;
    /** Element #3. */
    private final T3 value3;

    /**
     * Creates a new instance.
     *
     * @param t1
     *            element #1
     * @param t2
     *            element #2
     * @param t3
     *            element #3
     */
    private Tuple3(T1 t1, T2 t2, T3 t3) {
        value1 = t1;
        value2 = t2;
        value3 = t3;
    }

    /**
     * Creates a new instance.
     *
     * @param 
     *            the type of element #1
     * @param 
     *            the type of element #2
     * @param 
     *            the type of element #3
     * @param t1
     *            element #1
     * @param t2
     *            element #2
     * @param t3
     *            element #3
     *
     * @return the new instance
     */
    public static  Tuple3 of(T1 t1, T2 t2, T3 t3) {
        return new Tuple3<>(t1, t2, t3);
    }

    /**
     * Returns an empty tuple (consisting of {@code null} elements).
     *
     * @param 
     *            the type of element #1
     * @param 
     *            the type of element #2
     * @param 
     *            the type of element #3
     *
     * @return an empty tuple
     */
    @SuppressWarnings("unchecked")
    public static  Tuple3 empty() {
        return (Tuple3) EMPTY;
    }

    /**
     * Makes a tuple from the first three elements provided by the given source.
     *
     * @param 
     *            the type of the source's elements
     * @param source
     *            the source to process. It must provide at least three
     *            elements.
     *
     * @return a tuple
     *
     * @throws NoSuchElementException
     *             if the source provides too few elements
     */
    public static  Tuple3 from(Iterable source) {
        return from(source.iterator());
    }

    /**
     * Makes a tuple from the first three elements provided by the given source.
     *
     * @param 
     *            the type of the source's elements
     * @param source
     *            the source to process. It must provide at least three
     *            elements.
     *
     * @return a tuple
     *
     * @throws NoSuchElementException
     *             if the source provides too few elements
     */
    public static  Tuple3 from(Iterator source) {
        return of(source.next(), source.next(), source.next());
    }

    /**
     * Returns an iterable zipping the elements from given source iterables.
     *
     * 

* The resulting iterables returns tuples from the elements provided by the * source iterables and returns as many elements as the shorter of the * source iterables. * * @param * the type of element #1 * @param * the type of element #2 * @param * the type of element #3 * @param source1 * the source of elements. It must not be {@code null}. * @param source2 * the source of elements. It must not be {@code null}. * @param source3 * the source of elements. It must not be {@code null}. * * @return a zipping iterable */ public static Iterable> zip(Iterable source1, Iterable source2, Iterable source3) { Objects.requireNonNull(source1); Objects.requireNonNull(source2); Objects.requireNonNull(source3); // Rather not make a lambda, it might change return new Iterable>() { /** * @see java.lang.Iterable#iterator() */ public Iterator> iterator() { return Tuple3.zip(source1.iterator(), source2.iterator(), source3.iterator()); } }; } /** * Returns an iterator zipping the elements from given source iterators. * *

* The resulting iterator returns tuples from the elements provided by the * source iterators and returns as many elements as the shorter of the * source iterators. * * @param * the type of element #1 * @param * the type of element #2 * @param * the type of element #3 * @param source1 * the source of elements. It must not be {@code null}. * @param source2 * the source of elements. It must not be {@code null}. * @param source3 * the source of elements. It must not be {@code null}. * * @return a zipping iterator */ public static Iterator> zip(Iterator source1, Iterator source2, Iterator source3) { Objects.requireNonNull(source1); Objects.requireNonNull(source2); Objects.requireNonNull(source3); return new Iterator>() { /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return source1.hasNext() && source2.hasNext() && source3.hasNext(); } /** * @see java.util.Iterator#next() */ public Tuple3 next() { return Tuple3.of(source1.next(), source2.next(), source3.next()); } }; } /** * Returns a stream zipping the elements from given source streams. * *

* The resulting stream returns tuples from the elements provided by the * source streams and returns as many elements as the shorter of the source * streams. * * @param * the type of element #1 * @param * the type of element #2 * @param * the type of element #3 * @param source1 * the source of elements. It must not be {@code null}. * @param source2 * the source of elements. It must not be {@code null}. * @param source3 * the source of elements. It must not be {@code null}. * * @return a zipping stream */ public static Stream> zip(Stream source1, Stream source2, Stream source3) { final Iterator> it = zip(source1.iterator(), source2.iterator(), source3.iterator()); return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, 0), false); } /** * @see java.lang.Object#toString() */ @Override public String toString() { return String.format("(%s, %s, %s)", value1, value2, value3); } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof Tuple3) { final Tuple3 o = (Tuple3) obj; return Objects.equals(value1, o.value1) && Objects.equals(value2, o.value2) && Objects.equals(value3, o.value3); } return false; } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return Objects.hash(value1, value2, value3); } /** * Returns element #1. * * @return element #1 */ public T1 get1() { return value1; } /** * Returns element #2. * * @return element #2 */ public T2 get2() { return value2; } /** * Returns element #3. * * @return element #3 */ public T3 get3() { return value3; } /** * Returns a tuple with element #1 modified to the given value. * * @param * the type of the value * @param value * the value to set * * @return a tuple with element #1 modified to the given value */ public Tuple3 set1(V value) { return of(value, value2, value3); } /** * Returns a tuple with element #2 modified to the given value. * * @param * the type of the value * @param value * the value to set * * @return a tuple with element #2 modified to the given value */ public Tuple3 set2(V value) { return of(value1, value, value3); } /** * Returns a tuple with element #3 modified to the given value. * * @param * the type of the value * @param value * the value to set * * @return a tuple with element #3 modified to the given value */ public Tuple3 set3(V value) { return of(value1, value2, value); } /** * Returns a tuple with element #1 mapped with the given function. * * @param * the type of the function result * @param mapping * the function to apply. It must not be {@code null}. * * @return a tuple with element #1 mapped with the given function */ public Tuple3 map1(Function mapping) { return of(mapping.apply(value1), value2, value3); } /** * Returns a tuple with element #2 mapped with the given function. * * @param * the type of the function result * @param mapping * the function to apply. It must not be {@code null}. * * @return a tuple with element #2 mapped with the given function */ public Tuple3 map2(Function mapping) { return of(value1, mapping.apply(value2), value3); } /** * Returns a tuple with element #3 mapped with the given function. * * @param * the type of the function result * @param mapping * the function to apply. It must not be {@code null}. * * @return a tuple with element #3 mapped with the given function */ public Tuple3 map3(Function mapping) { return of(value1, value2, mapping.apply(value3)); } /** * Passes element #1 to the specified consumer. * * @param consumer * the consumer to call. It must not be {@code null}. * * @return this instance */ public Tuple3 use1(Consumer consumer) { consumer.accept(value1); return this; } /** * Passes element #2 to the specified consumer. * * @param consumer * the consumer to call. It must not be {@code null}. * * @return this instance */ public Tuple3 use2(Consumer consumer) { consumer.accept(value2); return this; } /** * Passes element #2 to the specified consumer. * * @param consumer * the consumer to call. It must not be {@code null}. * * @return this instance */ public Tuple3 use3(Consumer consumer) { consumer.accept(value3); return this; } /** * Returns the first two elements as a tuple. * * @return the first two elements as a tuple */ public Tuple2 head() { return Tuple2.of(value1, value2); } /** * Returns the last two elements as a tuple. * * @return the last two elements as a tuple */ public Tuple2 tail() { return Tuple2.of(value2, value3); } /** * Returns the first and the last elements as a tuple. * * @return the first and the last elements as a tuple */ public Tuple2 outer() { return Tuple2.of(value1, value3); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy