Explain Codes LogoExplain Codes Logo

A Java collection of value pairs? (tuples?)

java
prompt-engineering
best-practices
collections
Nikita BarsukovbyNikita BarsukovΒ·Sep 19, 2024
⚑TLDR

Key-value pairs in Java can conveniently be handled using AbstractMap.SimpleEntry:

SimpleEntry<String, Integer> pair = new SimpleEntry<>("apple", 1);

Alternatively, using Map.entry comes in handy:

Entry<String, Integer> pair = Map.entry("apple", 1); // 🍎

Dealing with multi-value tuples? Try Apache Commons Lang:

Triple<String, Integer, Double> triple = Triple.of("apple", 1, 2.50);

These efficient techniques enable you to curate related data items without the need for custom classes.

Java 16 and records

As of Java 16, records offer an elegant way to create data containers:

record Pair<K, V>(K key, V value) { } // Java 16 hitting the gym, getting in Pair shape! Pair<String, Integer> fruitCount = new Pair<>("banana", 42); // 🍌

Records provide immutable data carriers equipped with accessors and deconstruction patterns. It's as compact as it gets!

Custom tuple list for organized storage

For organized storage and order maintenance, create a custom TupleList class:

class TupleList<K, V> extends ArrayList<Entry<K, V>> { // extending ArrayList, but with more calories! public void addPair(K key, V value) { // calories = pairs add(new AbstractMap.SimpleEntry<>(key, value)); // consuming calories } } TupleList<String, Integer> inventory = new TupleList<>(); inventory.addPair("grape", 100); // πŸ‡: 100, feeling healthy yet?

Efficient handling of primitive types

Eclipse Collections offers efficient primitive pair classes which significantly reduce autoboxing overhead:

IntObjectPair<String> primPair = PrimitiveTuples.pair(10, "diamond"); // πŸ’Ž for just 10? What a steal!

Pair creation with ease

Static factory methods

Cheer up because Lombok and Android's Pair bring to you the static constructors:

@Value(staticConstructor = "of") // the static constructor, not of an Avengers kind πŸ¦Έβ€β™‚οΈ class LombokPair<A, B> { A left; B right; } // Android example, now without Google Play services πŸ˜‰: Pair<String, Integer> androidPair = Pair.create("key", 42);

These methods deliver null safety with less verbosity.

Safeguard your pairs

Ensure immutability of pairs when designing your Pair class for safe sharing across the codebase:

class ImmutablePair<K, V> { // no mutating pairs, like X-men private final K key; private final V value; public ImmutablePair(K key, V value) { this.key = key; this.value = value; } // Getters here, setters not invited 🚫 }

Don't forget to implement hashCode and equals to use Pairs in hash-based collections.

More tricks up your sleeve

The Power of "of" methods

Subclass ArrayList to add pairs using a custom "of" method:

class MyAwesomeList<K, V> extends ArrayList<Entry<K, V>> { // because we are awesome static <K, V> Entry<K, V> of(K a, V b) { return new AbstractMap.SimpleEntry<>(a, b); } }

Adding pairs now feels like a breeze:

var awesomeList = new MyAwesomeList<>(); awesomeList.add(MyAwesomeList.of("mango", 5)); // πŸ₯­ added without breaking a sweat!

Immutable entries

Jump on the Java 9 bandwagon. Creating immutable pairs has never been easier:

Entry<String, Integer> frozenPair = Map.entry("winter", -5); // for chilly winters β›„

Use this in modern Java for trustable and read-only data.

Comparing pairs

Need to sort your pairs? Make your Pair class implement Comparable:

class ComparablePair<K extends Comparable<K>, V extends Comparable<V>> implements Comparable<ComparablePair<K, V>> { // In Pair we compareπŸ¦‰ }

This lets you sort collections of pairs depending on key-value semantics.