Implementing Value Pair Collections in Java: From Custom Pair Classes to Modern Solutions

Nov 09, 2025 · Programming · 12 views · 7.8

Keywords: Java value pair collections | generic Pair class | AbstractMap.SimpleEntry | record classes | type safety

Abstract: This article provides an in-depth exploration of value pair collection implementations in Java, focusing on the design and implementation of custom generic Pair classes, covering key features such as immutability, hash computation, and equality determination. It also compares Java standard library solutions like AbstractMap.SimpleEntry, Java 9+ Map.entry methods, third-party library options, and modern implementations using Java 16 records, offering comprehensive technical references for different Java versions and scenarios. Through detailed code examples and performance analysis, the article helps developers choose the most suitable value pair storage solutions.

Background of Value Pair Collection Requirements

In Java programming, there is often a need to handle collections of elements consisting of two values of different types. Unlike Maps, these collections do not require one value to serve as a unique key but need to maintain insertion order. For example, storing a series of string and integer pairs like <String, Integer>, where the string is not a unique identifier.

Core Implementation of Custom Pair Class

Based on the best answer from the Q&A data, we can design a type-safe, immutable generic Pair class. This implementation avoids the type casting issues associated with Object arrays while being more concise than creating full classes.

public class Pair<L, R> {
    private final L left;
    private final R right;

    public Pair(L left, R right) {
        assert left != null;
        assert right != null;
        this.left = left;
        this.right = right;
    }

    public L getLeft() { return left; }
    public R getRight() { return right; }

    @Override
    public int hashCode() { 
        return left.hashCode() ^ right.hashCode(); 
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Pair)) return false;
        Pair pairo = (Pair) o;
        return this.left.equals(pairo.getLeft()) &&
               this.right.equals(pairo.getRight());
    }
}

Key features of this implementation include: generic type parameters ensuring compile-time type safety; final fields guaranteeing immutability; overridden hashCode method using XOR operation for reasonable hash distribution; equals method performing strict value equality comparison.

Collection Operation Examples

Using the custom Pair class to create ordered collections:

List<Pair<String, Integer>> pairList = new ArrayList<>();
pairList.add(new Pair<>("Alice", 25));
pairList.add(new Pair<>("Bob", 30));

// Iteration and access
for (Pair<String, Integer> pair : pairList) {
    System.out.println(pair.getLeft() + ": " + pair.getRight());
}

Java Standard Library Alternatives

The Java standard library provides several built-in value pair implementations:

AbstractMap.SimpleEntry (Java 6+)

List<Map.Entry<String, Integer>> entries = new ArrayList<>();
entries.add(new AbstractMap.SimpleEntry<>("Key1", 1));
entries.add(new AbstractMap.SimpleEntry<>("Key2", 2));

Map.entry (Java 9+)

List<Map.Entry<String, Integer>> entries = List.of(
    Map.entry("Name1", 100),
    Map.entry("Name2", 200)
);

Third-Party Library Solutions

Several popular libraries provide mature Pair implementations:

Apache Commons Lang

import org.apache.commons.lang3.tuple.Pair;

List<Pair<String, Integer>> pairs = new ArrayList<>();
pairs.add(Pair.of("Left", 1));
pairs.add(Pair.of("Right", 2));

JavaFX Pair (Java 8+)

import javafx.util.Pair;

List<Pair<String, Integer>> pairs = new ArrayList<>();
pairs.add(new Pair<>("First", 10));
pairs.add(new Pair<>("Second", 20));

Modern Java Record Implementation

Java 16 introduced record classes that provide more concise syntax for value pairs:

public record Pair<K, V>(K key, V value) {
    public static <K, V> Pair<K, V> of(K key, V value) {
        return new Pair<>(key, value);
    }
}

// Usage example
List<Pair<String, Integer>> records = new ArrayList<>();
records.add(Pair.of("Record1", 100));
records.add(Pair.of("Record2", 200));

Performance and Memory Considerations

Based on discussions about memory efficiency in reference articles, value pair implementations need to consider object creation overhead. For high-frequency creation scenarios:

Best Practice Recommendations

When choosing value pair implementations, consider:

  1. Java version compatibility: Select appropriate solutions based on target environment
  2. Immutability requirements: Immutable implementations are recommended for most scenarios
  3. Third-party dependencies: Evaluate costs and benefits of introducing external libraries
  4. Code readability: Consider using named classes instead of generic Pairs when semantics are clear
  5. Performance requirements: For high-frequency scenarios, consider object reuse or primitive type solutions

Conclusion

Java offers multiple choices for implementing value pair collections, ranging from simple custom Pair classes to mature solutions provided by standard libraries and third-party libraries. Developers should choose the most suitable implementation based on specific requirements, Java versions, and performance needs. With the evolution of the Java language, new features like record classes provide more modern and concise solutions for value pair processing.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.