# Package de.caff.generics.tuple

Tuple classes.

See: Description

- Interface Summary
  Interface | Description
  --- | ---
  ITuple2<T1,T2> | General interface for immutable 2-tuples.
  ITuple3<T1,T2,T3> | General interface for immutable 3-tuples.
  ITuple4<T1,T2,T3,T4> | General interface for immutable 4-tuples.
  ITuple5<T1,T2,T3,T4,T5> | General interface for immutable 5-tuples.
  ITuple6<T1,T2,T3,T4,T5,T6> | General interface for immutable 6-tuples.
  ITuple7<T1,T2,T3,T4,T5,T6,T7> | General interface for immutable 7-tuples.
  ITuple8<T1,T2,T3,T4,T5,T6,T7,T8> | General interface for immutable 8-tuples.
  ITuple9<T1,T2,T3,T4,T5,T6,T7,T8,T9> | General interface for immutable 9-tuples.

- Class Summary
  Class | Description
  --- | ---
  ITuple2.Base<T1,T2> | Abstract base implementation of a 2-tuple.
  ITuple3.Base<T1,T2,T3> | Abstract base implementation of a 3-tuple.
  ITuple4.Base<T1,T2,T3,T4> | Abstract base implementation of a 4-tuple.
  ITuple5.Base<T1,T2,T3,T4,T5> | Abstract base implementation of a 5-tuple.
  ITuple6.Base<T1,T2,T3,T4,T5,T6> | Abstract base implementation of a 6-tuple.
  ITuple7.Base<T1,T2,T3,T4,T5,T6,T7> | Abstract base implementation of a 7-tuple.
  ITuple8.Base<T1,T2,T3,T4,T5,T6,T7,T8> | Abstract base implementation of a 8-tuple.
  ITuple9.Base<T1,T2,T3,T4,T5,T6,T7,T8,T9> | Abstract base implementation of a 9-tuple.
  NTuple2<T1,T2> | Immutable tuple with 2 nullable elements.
  NTuple3<T1,T2,T3> | Immutable tuple with 3 nullable elements.
  NTuple4<T1,T2,T3,T4> | Immutable tuple with 4 nullable elements.
  NTuple5<T1,T2,T3,T4,T5> | Immutable tuple with 5 nullable elements.
  NTuple6<T1,T2,T3,T4,T5,T6> | Immutable tuple with 6 nullable elements.
  NTuple7<T1,T2,T3,T4,T5,T6,T7> | Immutable tuple with 7 nullable elements.
  NTuple8<T1,T2,T3,T4,T5,T6,T7,T8> | Immutable tuple with 8 nullable elements.
  NTuple9<T1,T2,T3,T4,T5,T6,T7,T8,T9> | Immutable tuple with 9 nullable elements.
  Tuple | Tuple helper class.
  Tuple2<T1,T2> | Immutable tuple with 2 non-null elements.
  Tuple3<T1,T2,T3> | Immutable tuple with 3 non-null elements.
  Tuple4<T1,T2,T3,T4> | Immutable tuple with 4 non-null elements.
  Tuple5<T1,T2,T3,T4,T5> | Immutable tuple with 5 non-null elements.
  Tuple6<T1,T2,T3,T4,T5,T6> | Immutable tuple with 6 non-null elements.
  Tuple7<T1,T2,T3,T4,T5,T6,T7> | Immutable tuple with 7 non-null elements.
  Tuple8<T1,T2,T3,T4,T5,T6,T7,T8> | Immutable tuple with 8 non-null elements.
  Tuple9<T1,T2,T3,T4,T5,T6,T7,T8,T9> | Immutable tuple with 9 non-null elements.
  Tuples | Tuple creation and type casting.

## Package de.caff.generics.tuple Description

Tuple classes.

Tuples provide a way of creating a small group which can hold 2 to 9 objects (called elements here) of different types. Sp Tuples are usually small, and as the arguments are not named in many cases a dedicated class is the better choice. But for temporary usage, e.g. as return type of functions, tuples are quite handy, especially because the functions in the library accept a tuple when the tuple element types are compatible to the function's argument types.

Tuples here come in 3 flavors which are differing whether `null` elements are allowed.

- ITuple: Interfaces `ITuple2` to `ITuple9` provide the basic access methods, including access with reordering or as tuples of different size. They don't make any statement about the `null`-ness of their elements (meaning that they obviously could be `null`).

  Both other tuple types provided here implement the appropriate interface. So you can use the interface in cases where you want to handle both types together. Furthermore these interfaces provide a simple way to make some of your classes look like a tuple where tuples are required.

- Tuple: The concrete classes `Tuple2` to `Tuple9` are small immutable containers used to keep the elements. They only allow non-null elements.
- NTuple: The concrete classes `NTuple2` to `NTuple9` are small immutable containers used to keep the elements. They allow null elements.

## Tuple Creation

The concrete tuples can be created in 3 ways: by constructor, using one of the static `of(...)`/`ofNullable(...)` methods of class `Tuple`, or by statically importing the `T(...)`/`N(...)` methods of class `Tuples` (ordered by decreasing typing).

      t1 = new Tuple3<>(a, b, c);
      t2 = Tuple.of(a, b, c);
      t3 = T(a, b, c);       // requires import static de.caff.generics.tuple.Tuples.T
      assert t1.equals(t2);
      assert t2.equals(t3);

Recommended are the last two ways, decide according to your preferences.

`Tuples` also provides methods for casting a tuple's type in cases where the compiler is unhappy but you know it shouldn't (see e.g. `Tuples.downCast(de.caff.generics.tuple.Tuple2)`).

## Accessing Tuple Elements

Access to the tuple's elements is done by methods which name consists of an underscore and a number. The number starts with 1 for the first element (i.e. `_1()`. For smaller tuples there are also accessors which return an reordered tuple which also start with an underscore, followed by the required order, e.g. in a 3-tuple the method `_312()` will return a 3-tuple with the same elements, but ordered 3,1,2. There is no need for including all elements. For the same 3-tuple the method `_31()` would return a 2-tuple with the elements 3 and 1.

For the larger tuples providing these methods would result in a combinatorial catastrophe (i.e. large classes and long compile times), therefore no reordering on the same level is provided, and extracting smaller tuples is only provided in order. E.g. method `Tuple9._13579()` will return a 5-tuple created from the first, the third, the fifth, the seventh and the ninth element of the original 9-tuple. But there is no `_54321()` method (because there would have to be 15120 of these "select an arbitrarily ordered 5-tuple" methods).

## Tuples and Functions

Sometimes creating a 2-tuple or 3-tuple is just good enough. E.g. when returning a function result, and therefore the tuples here provide a way to call a function on them where they expand themselves to the parameters of the given function, see e.g. `ITuple2.invoke(java.util.function.BiFunction)` or `ITuple3.invoke(de.caff.generics.function.Function3)`)}.

The same is true for consumers/procedures (e.g. `ITuple2.sendTo(java.util.function.BiConsumer)` or `ITuple3.sendTo(de.caff.generics.function.Procedure3)` and predicates (e.g. `ITuple2.testBy(java.util.function.BiPredicate)` of `ITuple3.testBy(de.caff.generics.function.Predicate3)`.

2 or more argument function, procedure and predicate implementations defined in this library will also expose a 1-argument default method which accepts a tuple of correct size and types. Thus a 3-argument function `Function3<R,A,B,C>` will not only provide a method

      R apply(A a, B b, C c)

but also a method

      R apply(@NotNull Tuple<? extends A, ? extends B, ? extends C> tuple)

This requires a non-`null` argument because the tuple will be expanded inside the method, but you can make use of `Function1.applyNonNull(java.lang.Object, java.lang.Object)` in order to achieve this. Standard Java 8 does not have something similar. but you can wrap a standard Java `Function` with `Function1.from(java.util.function.Function)`. Similar things (special non-null invoke and wrapping standard Java equivalents) work with `Procedure1` and `Predicate1`.

## Last Notes

The tuple classes are created programmatically. It would be awful to write and test all this combinatorical access methods. The creation code is quite special and not included. For simple combinatorics helpers see `de.caff.generics.util.combi`.