Repository: TheAlgorithms/Java
File: src/main/java/com/thealgorithms/conversions/UnitsConverter.java (Java)

Code before:
package com.thealgorithms.conversions;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;

public final class UnitsConverter {
    private final Map<Pair<String, String>, AffineConverter> conversions;
    private final Set<String> units;

    private static void putIfNeeded(Map<Pair<String, String>, AffineConverter> conversions, final String inputUnit, final String outputUnit, final AffineConverter converter) {
        if (!inputUnit.equals(outputUnit)) {
            final var key = Pair.of(inputUnit, outputUnit);
            if (!conversions.containsKey(key)) {
                conversions.put(key, converter);
            }
        }
    }

    private static Map<Pair<String, String>, AffineConverter> addInversions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
        Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
        for (final var curConversion : knownConversions.entrySet()) {
            final var inputUnit = curConversion.getKey().getKey();
            final var outputUnit = curConversion.getKey().getValue();
            putIfNeeded(res, inputUnit, outputUnit, curConversion.getValue());
            putIfNeeded(res, outputUnit, inputUnit, curConversion.getValue().invert());
        }
        return res;
    }

    private static Map<Pair<String, String>, AffineConverter> addCompositions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
        Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
        for (final var first : knownConversions.entrySet()) {

Review comment (refactor):
For me it is better to use `Pair<K, V>`, it is short and clear.
But if you want to achieve simplicity, what do you think to simplify Pair usage and introduce such class, for easier reading:

```
public final class ConversionKey {
    private final String inputUnit;
    private final String outputUnit;

    public ConversionKey(String inputUnit, String outputUnit) {
        this.inputUnit = inputUnit;
        this.outputUnit = outputUnit;
    }

    public String getInputUnit() {
        return inputUnit;
    }

    public String getOutputUnit() {
        return outputUnit;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ConversionKey that = (ConversionKey) o;
        return Objects.equals(inputUnit, that.inputUnit) &&
               Objects.equals(outputUnit, that.outputUnit);
    }

    @Override
    public int hashCode() {
        return Objects.hash(inputUnit, outputUnit);
    }

    @Override
    public String toString() {
        return "ConversionKey{" +
                "inputUnit='" + inputUnit + '\'' +
                ", outputUnit='" + outputUnit + '\'' +
                '}';
    }
}
```

Code after:
package com.thealgorithms.conversions;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.tuple.Pair;

public final class UnitsConverter {
    private final Map<Pair<String, String>, AffineConverter> conversions;
    private final Set<String> units;

    private static void putIfNeeded(Map<Pair<String, String>, AffineConverter> conversions, final String inputUnit, final String outputUnit, final AffineConverter converter) {
        if (!inputUnit.equals(outputUnit)) {
            final var key = Pair.of(inputUnit, outputUnit);
            conversions.putIfAbsent(key, converter);
        }
    }

    private static Map<Pair<String, String>, AffineConverter> addInversions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
        Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
        for (final var curConversion : knownConversions.entrySet()) {
            final var inputUnit = curConversion.getKey().getKey();
            final var outputUnit = curConversion.getKey().getValue();
            putIfNeeded(res, inputUnit, outputUnit, curConversion.getValue());
            putIfNeeded(res, outputUnit, inputUnit, curConversion.getValue().invert());
        }
        return res;
    }

    private static Map<Pair<String, String>, AffineConverter> addCompositions(final Map<Pair<String, String>, AffineConverter> knownConversions) {
        Map<Pair<String, String>, AffineConverter> res = new HashMap<Pair<String, String>, AffineConverter>();
        for (final var first : knownConversions.entrySet()) {
            final var firstKey = first.getKey();
            putIfNeeded(res, firstKey.getKey(), firstKey.getValue(), first.getValue());