Interface  Description 

ITuple2<T1,T2> 
General interface for immutable 2tuples.

ITuple3<T1,T2,T3> 
General interface for immutable 3tuples.

ITuple4<T1,T2,T3,T4> 
General interface for immutable 4tuples.

ITuple5<T1,T2,T3,T4,T5> 
General interface for immutable 5tuples.

ITuple6<T1,T2,T3,T4,T5,T6> 
General interface for immutable 6tuples.

ITuple7<T1,T2,T3,T4,T5,T6,T7> 
General interface for immutable 7tuples.

ITuple8<T1,T2,T3,T4,T5,T6,T7,T8> 
General interface for immutable 8tuples.

ITuple9<T1,T2,T3,T4,T5,T6,T7,T8,T9> 
General interface for immutable 9tuples.

Class  Description 

ITuple2.Base<T1,T2> 
Abstract base implementation of a 2tuple.

ITuple3.Base<T1,T2,T3> 
Abstract base implementation of a 3tuple.

ITuple4.Base<T1,T2,T3,T4> 
Abstract base implementation of a 4tuple.

ITuple5.Base<T1,T2,T3,T4,T5> 
Abstract base implementation of a 5tuple.

ITuple6.Base<T1,T2,T3,T4,T5,T6> 
Abstract base implementation of a 6tuple.

ITuple7.Base<T1,T2,T3,T4,T5,T6,T7> 
Abstract base implementation of a 7tuple.

ITuple8.Base<T1,T2,T3,T4,T5,T6,T7,T8> 
Abstract base implementation of a 8tuple.

ITuple9.Base<T1,T2,T3,T4,T5,T6,T7,T8,T9> 
Abstract base implementation of a 9tuple.

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 nonnull elements.

Tuple3<T1,T2,T3> 
Immutable tuple with 3 nonnull elements.

Tuple4<T1,T2,T3,T4> 
Immutable tuple with 4 nonnull elements.

Tuple5<T1,T2,T3,T4,T5> 
Immutable tuple with 5 nonnull elements.

Tuple6<T1,T2,T3,T4,T5,T6> 
Immutable tuple with 6 nonnull elements.

Tuple7<T1,T2,T3,T4,T5,T6,T7> 
Immutable tuple with 7 nonnull elements.

Tuple8<T1,T2,T3,T4,T5,T6,T7,T8> 
Immutable tuple with 8 nonnull elements.

Tuple9<T1,T2,T3,T4,T5,T6,T7,T8,T9> 
Immutable tuple with 9 nonnull elements.

Tuples 
Tuple creation and type casting.

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.
Tuple2
to Tuple9
are small immutable containers used to keep the elements. They only allow nonnull elements.
NTuple2
to NTuple9
are small immutable containers used to keep the elements. They allow null elements.
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)
).
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 3tuple the method _312()
will return a 3tuple with the same elements,
but ordered 3,1,2. There is no need for including all elements. For the same 3tuple the method
_31()
would return a 2tuple 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 5tuple created from
the first, the third, the fifth, the seventh and the ninth element of the original 9tuple.
But there is no _54321()
method (because there would have to be 15120 of these
"select an arbitrarily ordered 5tuple" methods).
Sometimes creating a 2tuple or 3tuple 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 1argument default method which accepts a tuple of correct size and types. Thus a 3argument
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 nonnull
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 nonnull invoke and wrapping standard Java equivalents) work
with Procedure1
and Predicate1
.
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
.