Introduction
- Tuple is data structure that is designed to store heterogeneous objects.
- It’s useful when we want to store or return heterogeneous object such as Customer object which consist of name, age , salary etc.
- In Java we don’t have tuple data structure out of the box provided by SDK, but we can use either Collections such as array or arraylist.
- We can also create our own Tuple class to provide such features.
- Other than that we also have some libraries that support creating tuple in java.
Use Case
- Let’s say we want to create customer object that would store name , age .
name being string while age is integer. - Now In java if we want to store this heterogeneous data then we have few options in Java. Let’s explore them one by one.
Using List as Tuple
- We generally store list to store a particular data type such as integer , string or even custom type .
- But we can store object data type in List as well although its not recommended and can result in producing bugs in the software.Thats why generics introduced in java to have compile time check on Collection so that developers define what data type they want to store.
String userName = "Sam";
Integer age =23;
List customer = Arrays.asList(userName,age);
System.out.println("customer name : "+customer.get(0));
System.out.println("customer age : "+customer.get(1));
- As we can see we have created customer as list and storing heterogeneous data types, but this not recommended to avoid bugs in the code.
Implementing Custom Tuple Class
- We can also create our custom tuple implementation.
Pair
- Lets implement tuple of 2 elements . In order to we have to use generics to store element of any type.
- Although our tuple is immutable by design but we can create mutable tuple as well.
import java.io.Serializable;
public class Tuple2<T,U> implements Serializable {
private static final long serialVersionUID = -2344986941139471507L;
private final T val1;
private final U val2;
public Tuple2(final T val1, final U val2) {
this.val1 = val1;
this.val2 = val2;
}
public static <T,U> Tuple2 of(final T val1, final U val2){
return new Tuple2(val1,val2);
}
public T getVal1() {
return val1;
}
public U getVal2() {
return val2;
}
@Override
public String toString() {
return "Pair{" +
"val1=" + val1 +
", val2=" + val2 +
'}';
}
}
Triplet
- Similarly we can extend tuple of 2 elements idea to implement tuple of 3 or 4 and so on.
import java.io.Serializable;
public class Tuple3<T,U,V> implements Serializable {
private static final long serialVersionUID = -5193340612637235968L;
private final T val1;
private final U val2;
private final V val3;
public Tuple3(final T val1, final U val2, final V val3) {
this.val1 = val1;
this.val2 = val2;
this.val3 = val3;
}
public static <T,U> Tuple3 of(final T val1, final U val2, final U val3){
return new Tuple3(val1,val2,val3);
}
public T getVal1() {
return val1;
}
public U getVal2() {
return val2;
}
public V getVal3() {
return val3;
}
@Override
public String toString() {
return "Tuple3{" +
"val1=" + val1 +
", val2=" + val2 +
", val3=" + val3 +
'}';
}
}
Client Code
- Once our tuple implementation is ready we can use in of our client code.
- Please notice that our implementation is immutable so we can only initialize tuple either with constructor or using factory method to create instance. We don’t have setters to initialize the tuple.
public static void main(String[] args) {
// setup tuple
Tuple2<String,Integer> pair = new Tuple2<>("Sam Lee", 23);
// get tuple
System.out.println(pair.getVal1());
// setup tuple
Tuple2<Integer, String> pair1 = Tuple2.of(10, "Done");
System.out.println(pair1.getVal1());
// setup tuple
Tuple3<String,Integer,Integer> triplet = new Tuple3<>("Sam Lee", 23, 123);
System.out.println(triplet.toString());
}
Using Libraries
- we can use libraries as well to create tuple . There are few libraries such as
– Apache Commons Lang
– Javatuple - Let’s use Apache Commons Lang to implement tuple of 2 elements.
Since it’s third party library we need to import it using maven or gradle.
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
- We can implement immutablePair as well as mutablePair using apache commons to create tuple of 2 elements
- In case of mutablePair we can modify our tuple.
ImmutablePair<String, Integer> customer = ImmutablePair.of("Sam", 23);
System.out.println(customer.toString());
MutablePair<String, Integer> customer = MutablePair.of("Sam", 23);
System.out.println(customer.toString());
customer.setRight(30);
System.out.println(customer.toString());
Why Java Doesn’t have Tuple in built ?
- The reason for this is not so clear but one argument to support it is that java focuses more on readability so instead of have common container such as tuple to store the elements , it would be nice if we create Class for that object itself.
- In our example we can create specific class for customer instead of storing it in tuple.
- That would make our code more readable since type of the object would be clear and not generic tuple.
- But any way as developer we got many options to solve our issue to store heterogeneous data type.
Conclusion
- In this article we discuss different approached to store heterogeneous data type in java .
- We can either custom implement tuple , use third party libraries like javatuple or even we can create custom class.
Bonus Tip
- If you want to upskill your Java, you should definitely check out this bestseller course
Follow me on LinkedIn