Five alternatives to Pair class in Java
A Pair is a container to store a tuple of two objects. Java doesn’t really provide any implementation of the Pair class. This post will discuss various alternatives to the Pair class in Java.
Pair is often useful to track two objects together. It contains two fields, usually termed as first and second, capable of storing anything. Despite not having any meaningful relationship between the first and second field, programmers often miss this functionality in Java.
In the previous post, we have discussed how to implement our own Pair class in Java. This post will discuss workarounds available in Java to fill the desired gap, as discussed below:
1. Using Map.Entry<K,V> Interface
We can use Map.Entry<K,V> interface in Java which is similar to std::pair in C++. It is an excellent example of having a meaningful name that represents a key-value pair.
To create an entry representing a mapping from the specified key to the specified value, Java provides two concrete implementations of the Map.Entry interface, namely, AbstractMap.SimpleEntry and AbstractMap.SimpleImmutableEntry.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.AbstractMap; import java.util.HashSet; import java.util.Map; import java.util.Set; class Pair { // Return a map entry (key-value pair) from the specified values public static <T, U> Map.Entry<T, U> of(T first, U second) { return new AbstractMap.SimpleEntry<>(first, second); } } class Main { // Implement Pair class in Java using `Map.Entry` public static void main(String[] args) { Set<Map.Entry<String, Integer>> entries = new HashSet<>(); entries.add(Pair.of("Java", 50)); entries.add(Pair.of("C++", 30)); System.out.println(entries); // runs in Java 8 and above only entries.forEach(entry -> { if (entry.getKey().equals("Java")) { System.out.println(entry.getValue()); } }); } } |
Output:
[Java=50, C++=30]
50
2. Using Java 8 – javafx.util.Pair
Finally, after a long wait, a Pair<K,V> class is added in Java 8 in javafx.util package. The class represent key-value pairs and supports very basic operations like getKey(), getValue(), hashCode(), equals(java.lang.Object o), and toString() and has few methods inherited from java.lang.Object class. Well, something is better than nothing, huh?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import javafx.util.Pair; import java.util.ArrayList; import java.util.List; class Main { // Demonstrate `javafx.util.Pair` class introduced in Java 8 and above public static void main(String[] args) { List<Pair<String, Integer>> entries = new ArrayList<>(); entries.add(new Pair<>("C", 20)); entries.add(new Pair<>("C++", 30)); // print first pair using `getKey()` and `getValue()` method System.out.println("{" + entries.get(0).getKey() + ", " + entries.get(0).getValue() + "}"); // print second pair using `getKey()` and `getValue()` method System.out.println("{" + entries.get(1).getKey() + ", " + entries.get(1).getValue() + "}"); } } |
Output:
{C, 20}
{C++, 30}
3. Using Apache Commons Lang
Apache Commons Lang Library also provides a Pair<L,R> utility class whose elements are left and right. It is defined as abstract and implements the Map.Entry interface, where the key is left and the value is right.
It has the Pair.of() method that can be used to obtain an immutable pair from specified pair of objects. Its subclass MutablePair is mutable, whereas ImmutablePair is immutable. However, the type of the object stored in ImmutablePair can itself may be mutable.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import java.util.ArrayList; import java.util.List; class Main { // Demonstrate Pair class provided Apache Commons Library in Java public static void main(String[] args) { List<Pair<String, Integer>> entries = new ArrayList<>(); entries.add(new MutablePair<>("C", 20)); // using `MutablePair` entries.add(new ImmutablePair<>("C++", 30)); // using `ImmutablePair` entries.add(Pair.of("Java", 50)); // using `Pair.of()` System.out.println(entries); // 1. The first pair is mutable Pair<String, Integer> pair = entries.get(0); pair.setValue(100); // works fine // printing pair using `getKey()` and `getValue()` method System.out.println(pair.getKey() + ", " + pair.getValue()); // 2. The second pair is immutable pair = entries.get(1); try { pair.setValue(100); // runtime error } catch (UnsupportedOperationException ex) { System.out.println("UnsupportedOperationException thrown"); } // printing pair using `getLeft()` and `getRight()` method System.out.println(pair.getLeft() + ", " + pair.getRight()); // 3. The third pair is also immutable pair = entries.get(2); try { pair.setValue(100); // runtime error } catch (UnsupportedOperationException ex) { System.out.println("UnsupportedOperationException thrown"); } System.out.println(pair.getLeft() + ", " + pair.getRight()); } } |
Output:
[(C,20), (C++,30), (Java,50)]
C, 100
UnsupportedOperationException thrown
C++, 30
UnsupportedOperationException thrown
Java, 50
4. Using JavaTuples Library
Javatuples is another famous and simple Java library that deals with tuples. It provides a set of tuple Java classes ranging from one to ten elements. To serve our purpose, we can use Pair<A,B> class.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import org.javatuples.Pair; import java.util.ArrayList; import java.util.List; class Main { // Demonstrate Pair class provided by `JavaTuples` Library in Java public static void main(String[] args) { List<Pair<String, Integer>> pairs = new ArrayList<>(); pairs.add(Pair.with("Java", 50)); // using `Pair.with()` pairs.add(new Pair<>("C++", 30)); // using constructors // print first pair using `getValue0()` and `getValue1()` method System.out.println("{" + pairs.get(0).getValue0() + ", " + pairs.get(0).getValue1() + "}"); // print second pair using `getValue0()` and `getValue1()` method System.out.println("{" + pairs.get(1).getValue0() + ", " + pairs.get(1).getValue1() + "}"); } } |
Output:
{Java, 50}
{C++, 30}
5. Using Collections.singletonMap() method
Another approach is to use the Collections.singletonMap() in Java which is similar to Map.Entry<K,V> discussed earlier. It returns an immutable singleton map containing only the specified key-value pair mapping, which can be treated as a Pair.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; class Pair { // Return an immutable singleton map containing only the specified // key-value pair mapping public static <T, U> Map<T, U> of(T first, U second) { return Collections.singletonMap(first, second); } } class Tuple { // Implement Pair class in Java using `Collections.singletonMap()` public static void main(String[] args) { Set<Map<String, Integer>> entries = new HashSet<>(); entries.add(Pair.of("Java", 50)); entries.add(Pair.of("C++", 30)); System.out.println(entries); } } |
Output:
[{Java=50}, {C++=30}]
Finally, in Android projects, we can use the android.util.Pair class provided by the Android SDK.
That’s all about alternatives to the Pair class in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)