Java tuple – Working with tuples in Java

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

Table of Contents

1. What is tuple
2. Tuples 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 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. Tuples in Java

Java doesn’t have any such inbuilt data structure to support tuples. Whenever required, we can create a class that can act like a 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 a standard data structure is not possible in Java.

2.1. Comparison of Tuples vs Lists/Arrays

A 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 aim 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 a 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

Javatuples support 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 the 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. Features and advantages

Different types of tuples are:

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

4. Java Tuple Example – Common Operations

4.1. Creating a 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 a 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 in any tuple class based on our requirements.

4.2. Get 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 the 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 and 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.

A new element is added at the end of the 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. Iterating over values

All tuple classes 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. 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 straightforward, easy to use, and provides good performance.

Happy Learning !!

References:

Official Page of Javatuples

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.