Skip navigation links

Package de.caff.generics.tuple

Tuple classes.

See: Description

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.

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.

Skip navigation links