In this Java tutorial, we will learn about Java Tuple – a generic data structure and how we can use tuples in a Java program. Tuple, by default, are not present in Java programming language as data structure, so we will use one nice third-party library javatuples for it.

Table of Contents

1. What is tuple
2. Tuple in Java
3. Introduction of Javatuples 
4. Common Operations on Javatuples
5. Conclusion

1. What is tuple?

A tuple can be seen as an ordered collection of objects of different types. These objects do not necessarily relate to each other in any way, but collectively they will have some meaning.

For an example ["Sajal Chakraborty", "IT Professional", 32] can be a tuple where each value inside the tuple does not have any relation but this whole set of values can have some meaning in the application. For example, give tuple may represent an employee data with name, department and age.

Let’s see some more java tuple examples.

["Java", 1.8, "Windows"]
["Alex", 32, "New York", true]
[3, "Alexa", "howtodoinjava.com", 37000]

2. Tuple in Java

Java doesn’t have any such inbuilt data structure to support tuples. Whenever required, we can obviously create a class which can act like tuple.

Also, in Java part of the tuple functionality can be written using List or Array but those will not allow us to hold different types of data types by design. So we can say that heterogeneous tuple using standard data structure is not possible in Java.

2.1. Comparison of Tuples vs Lists/Arrays

Tuple is often compared with List as it looks very much like a list. But they differ in some aspects.

  1. A tuple is an object that can contain heterogeneous data. Lists are designed to store elements of a single type.
  2. Out of all data structures, a tuple is considered to be the fastest and they consume the least amount of memory.
  3. While array and list are mutable which means you can change their data value and modify their structures, a tuple is immutable.
  4. Like an array, a tuple is also fixed in size. That is why tuples aims to replace array completely as they are more efficient in all parameters.
  5. If you have a dataset which will be assigned only once in lifetime and its value should not change again, you need a tuple.

3. Javatuples library

3.1. javatuples maven dependency

javatuples library is present in the maven central repo and we can add this dependency to use the library.

<dependency>
	<groupId>org.javatuples</groupId>
	<artifactId>javatuples</artifactId>
	<version>1.2</version>
</dependency>

3.2. javatuples – classes

Java tuples supports tuples of size up to '10' and for each size it has provided a tuple implementation like below.

  • Unit (one element)
  • Pair (two elements)
  • Triplet (three elements)
  • Quartet (four elements)
  • Quintet (five elements)
  • Sextet (six elements)
  • Septet (seven elements)
  • Octet (eight elements)
  • Ennead (nine elements)
  • Decade (ten elements)

On top of above classes, it provides two more classes for easy representation of pairs. Those mostly same as Pair but has more verbose syntax.

  1. KeyValue
  2. LabelValue

3.3. javatuples – features

Different types of java tuple are:

  1. Type safe
  2. Immutable
  3. Iterable
  4. Serializable
  5. Comparable (implements Comparable)
  6. Implementing equals() and hashCode()
  7. Implementing toString()

4. Common Operations on Javatuples

4.1. Create tuple

4.1.1. Factory methods

Tuples objects are constructed by the provided factory method with() from each tuple class. For example to create a tuple of Pair we can use.

Pair<String, Integer> pair = Pair.with("Sajal", 12);
4.1.2. Constructor

We can also use the constructor of Pair.

Pair<String, Integer> person = new Pair<String, Integer>("Sajal", 12);
4.1.3. Collection or Iterable

We can create tuples from a Collection or Iterable, provided that collection has exact number of objects. In this case please remember that the number of items in the collection should match the type of the tuple that we want to create.

//Collection of 4 elements will create Quartet
List<String> listOf4Names = Arrays.asList("A1","A2","A3","A4");

Quartet<String, String, String, String> quartet = Quartet.fromCollection(listOf4Names);

System.out.println(quartet);

//Create pair with items starting from the specified index.
List<String> listOf4Names = Arrays.asList("A1","A2","A3","A4");

Pair<String, String> pair1 = Pair.fromIterable(listOf4Names, 2);

System.out.println(pair1);

Program output.

[A1, A2, A3, A4]
[A3, A4]

Similarly, we can create objects any tuple class based on our requirement.

4.2. Retrieve values

4.2.1. getValue() methods

We can get the values from the tuples by using its indexed getValueX() methods where 'X' denotes the element position inside tuple. For example, getValue0(), getValue1() etc.

Pair<String, Integer> pair = Pair.with("Sajal", 12);

System.out.println("Name : " + pair.getValue0());
System.out.println("Exp : " + pair.getValue1());

Program output.

Name : Sajal
Exp : 12

Please note that these get methods are type safe. It means compiler already knows the method return type based on the element values used to initialize the tuple.

4.2.2. getValue(int index) methods

Tuples have another method getValue(int index) which is not type safe. So we need to cast the value to the expected type when we are assigning to a variable.

Pair<String, Integer> pair = Pair.with("Sajal", 12);

System.out.println("Name : " + pair.getValue(0));
System.out.println("Exp : " + pair.getValue(1));

Program output.

Name : Sajal
Exp : 12
Classes KeyValue and LabelValue have methods as getKey()/getValue() and getLabel()/getValue(), respectively.

4.3. Set values

We can set values in tuples after they are created. We can do this by setAtX() method where 'X' is the index position where we want to set value.

Pair<String, Integer> pair = Pair.with("Sajal", 12);
        
//Modify the value
Pair<String, Integer> modifiedPair = pair.setAt0("Kajal");

System.out.println(pair);
System.out.println(modifiedPair);

Program output.

[Sajal, 12]
[Kajal, 12]

Please notice that tuples are immutable. So setAt() method returns same type of tuple with modified value. Original tuple is unchanged.

4.4. Add or remove elements

4.4.1. add() method

We can also add elements in Tuple which will return a new tuple type matching the number of elements. For example, if we add value an element to a Pair then we will get a Triplet object in return.

New element is added at the end of tuple.

Pair<String, Integer> pair = Pair.with("Sajal", 12);
        
Triplet<String, Integer, String> triplet = pair.add("IT Professional");

System.out.println(pair);
System.out.println(triplet);

Program output.

[Sajal, 12]
[Sajal, 12, IT Professional]

We can add one tuple object to another tuple as well. It will return the type of Tuple based on the number of elements present after addition.

Triplet<String, String, String> triplet = Triplet.with("Java", "C", "C++");
Quartet<String, String, String, String> quartet = triplet.addAt1("Python");

Septet septet = quartet.add(triplet);   //3 + 4 = 7

System.out.println(triplet);
System.out.println(quartet);
System.out.println(septet);

Program output.

[Java, C, C++]
[Java, Python, C, C++]
[Java, Python, C, C++, Java, C, C++]
4.4.2. addAt() method

By default, new elements are added at the end of the tuple. But we can also add elements in other positions of the tuple by using the addAtX() methods.

Triplet<String, String, String> triplet = Triplet.with("Java", "C", "C++");
Quartet<String, String, String, String> quartet = triplet.addAt1("Python");

System.out.println(triplet);
System.out.println(quartet);

Program output.

[Java, C, C++]
[Java, Python, C, C++]

4.5. Convert tuple to collection or array

Each tuple class provides asList() and toArray() methods which returns List and Array respectively.

//Convert to list
Quartet<String, Integer, String, Double> quartet1 = Quartet.with("A1",1,"A3",2.3);

List<Object> quartletList = quartet1.toList();

System.out.println(quartletList);

//Convert to array
Object[] quartletArr = quartet1.toArray();

System.out.println(Arrays.toString(quartletArr));

Program output.

[A1, 1, A3, 2.3]
[A1, 1, A3, 2.3]

Please note here that tuple can contain heterogeneous types so resulting type will be of List<Object> or Object[] accordingly.

4.6. Iteration

All tuple classes in javatuples implement the Iterable interface so they can be iterated in the same way as collections or arrays.

Quartet<String, Integer, String, Double> quartet1 = Quartet.with("A1",1,"A3",2.3);

for(Object obj : quartet1) {
	System.out.println(obj);
}

Program output.

A1
1
A3
2.3

4.7. More operations in java tuple

All tuple class has the following utility methods like collection and we can use those as per our requirement.

  • contains() – returns true if this tuple contains the specified element.
  • containsAll() – returns true if this tuple contains the all the specified elements.
  • indexOf() – returns the index of the first occurrence of the specified element.
  • lastIndexOf() – returns the index of the last occurrence of the specified element.

Tuples also provide the generic implementation of hashCode(), equals() and compareTo() methods which work fine with wrapper and string classes.

5. Java tuple – conclusion

In this Java tuple tutorial, we have seen how we can use tuples in java with javatuple library. So if you face any requirement of a data structure which store fixed number of heterogeneous elements, you can use this library. It is very simple, easy to use and provide good performance.

Happy Learning !!

References:

Official Page of Javatuples