How to Support Returning Two Values in Java

Java only returns one value from a method, but sometimes we’d like it to return more than one values, in this article, let’s take a look at some tricks to achieve this.

Let’s suppose we hope a method returning a pair of axises, representing a point(x,y) in the coordinate plane.

Using Java List

We can simply use a Java List to hold values of both axises when they are of the same data type.

    static List<Integer> returnsAxisPairAsList() {
        List<Integer> results = new ArrayList<>();
        results.add(10);
        results.add(12);
        return results;
    }

Using Java Array

Or if we want primitive return types, we can use Array instead.

    static int[] returnsAxisPairAsArrays() {
        int[] results = new int[2];
        results[0] = 10;
        results[1] = 12;
        return results;
    }

Using Java Map

We can also use a Java Map to get named key-value results from Java methods.

    static Map<String, Integer> returnsAxisPairAsMap() {
        Map<String, Integer> results = new HashMap<>();
        results.put("axisX", 10);
        results.put("axisY", 12);
        return results;
    }

Using Java Map Entry

The entry in the Java Map is actually a key-value pair, so we can use map entry as axis value holder: entry key as x-axis, entry value as y-axis.

It’s convenient when key and value are of different types.

    static AbstractMap.SimpleEntry<Integer, Double> returnsAxisPairAsAbstractMapEntry() {
        return new AbstractMap.SimpleEntry<Integer, Double>(10, 12.5);
    }

If we have Java 9, we can simple use Map.entry().

    static Map.Entry<Integer, Double> returnsAxisPairAsMapEntry() {
        return Map.entry(10, 12.5);
    }

To get the values of both axises, just use getKey() and getValue() from Map.Entry class.

    entry.getKey();
    entry.getValue();

Creating a Pair Class

We can implement a generic Pair class to hold the two values returned by method.

    static final class Pair<S, T> {
        private final S first;
        private final T second;

        private Pair(S first, T second) {
            this.first = first;
            this.second = second;
        }

        public static <S, T> Pair<S, T> of(S first, T second) {
            return new Pair<>(first, second);
        }

        public S getFirst() {
            return this.first;
        }

        public T getSecond() {
            return this.second;
        }
    }

To create a pair, use Pair.of() method:

    static Pair<Integer, Double> returnsCustomPair() {
        return Pair.of(10, 12.5);
    }

To get values from a pair:

    Integer x = pair.getFirst();
    Double y = pair.getSecond();

Creating a Wrapper Class

Instead of using array, list, map or a generic Pair class, we can consider creating a wrapper class which holds values we want a method to return. The benefits of this approach over using the above is it will make our codes much easier to understand.

    @Data
    @AllArgsConstructor
    static class Axis {
        private Integer x;
        private Double y;
    }

Using wrapper classes allow us get values with meaningful field names.


    // create an Axis object
    static Axis returnsWrapperObject() {
        return new Axis(10, 12.5);
    }

    // get values
    Integer x = axis.getX();
    Double y = axis.getY();