Three sum problem using HashMap in Java Given an array and a value, find all the triplets in the array whose sum is equal to the given value. For example, if the given array is {12, 3, 4, 1, 6, 9} and the given sum is 24, then this is one triplet (12, 3 and 9) which contributes to the total sum of 24.
Solution for given example:
6, 9, 9
6, 6, 12
3, 9, 12
Conditions:

The ordering of the numbers in the solution does not matter.

Duplicate triplet is not allowed.

A number is not allowed to be used multiple times.



This question was asked here.
Here is my code which addresses all the issues. One concern is the code looks a little muddy which I want to avoid in the production grade code. Any constructive feedback is appreciated.
Runtime: O(n2)
GitHub
public class ThreeSum {

    static class Triplet {
        final List&lt;Integer&gt; triplets;

        public Triplet(int x, int y, int z) {
            triplets = Arrays.asList(x, y, z);
            Collections.sort(triplets);
        }

        @Override
        public int hashCode() {
            return Objects.hash(triplets.get(0), triplets.get(1), triplets.get(2));
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Triplet) {

                Triplet other = (Triplet) o;
                return other.triplets.get(0) == this.triplets.get(0) &amp;&amp;
                        other.triplets.get(1) == this.triplets.get(1) &amp;&amp;
                        other.triplets.get(2) == this.triplets.get(2);
            }

            return false;
        }

        @Override
        public String toString() {
            return String.format(&quot;(%d, %d, %d)&quot;, triplets.get(0), triplets.get(1), triplets.get(2));
        }
    }

    public static Set&lt;Triplet&gt; findTriplets(int numbers[], int targetSum) {
        Set&lt;Triplet&gt; triplets = new HashSet&lt;&gt;();

        // insert all pairs in the look up table
        Map&lt;Integer, int[]&gt; lookup = new HashMap&lt;&gt;();
        for (int i = 0; i &lt; numbers.length - 1; i++) {
            for (int j = i + 1; j &lt; numbers.length; j++) {
                int total = numbers[i] + numbers[j];
                lookup.put(total, new int[]{i, j});
            }
        }

        // look for the complement, if found viola! here you go with the triplet
        for (int currentIndex = 0; currentIndex &lt; numbers.length; currentIndex++) {
            int complement = targetSum - numbers[currentIndex];

            if (lookup.containsKey(complement)) {
                int indexes[] = lookup.get(complement);

                if (currentIndex != indexes[0] &amp;&amp; currentIndex != indexes[1]) {
                    int x = numbers[indexes[0]], y = numbers[indexes[1]];
                    triplets.add(new Triplet(x, y, numbers[currentIndex]));
                }
            }
        }

        return triplets;
    }
}
You are storing the integers of a Triplet as a List internally, yet you are not really taking advantage of the interface List's functionality. For example:

return Objects.hash(triplets.get(0), triplets.get(1), triplets.get(2));


Why not simply do this:

return triplets.hashCode();


Or, another example:

return other.triplets.get(0) == this.triplets.get(0) &amp;&amp;
        other.triplets.get(1) == this.triplets.get(1) &amp;&amp;
        other.triplets.get(2) == this.triplets.get(2);


This can be replaced by this:

return other.triplets.equals(this.triplets);

There's an issue I didn't catch in the old question but which was already present there: Your code doesn't consider the possibility that the same sum is formed by more than one pair of numbers, because you are simply mapping integers to one pair of indices, and if you encounter a pair that adds up to a sum that is already stored in lookup, the old index pair gets overridden.

A way to overcome this problem could be to map the integers to a List&lt;int[]&gt;), but this would make things even more complicated, and I think the reason that this would get overly complicated is that you are, in fact, hard-coding a recursive process (first you create the pairs, then from the pairs you create the triplets etc.). You could instead try to write a method that accumulates all possible n-tuplets, with n being any arbitrary positive integer, through recursion, e.g. like this:


If n is 1, then return an array/list of all integers
If n is greater than 1, then iterate through the original array and, for every integer in it, combine this integer with all n-1-tuplets formed by the numbers that follow this integer in the array (taking only the following numbers and not the preceding numbers prevents duplicate tuplets that only differ in the order of the integers).


I imagine that this would be much easier to code than what you currently have (maybe this is also what you mean by your code being "muddy"), and also much more flexible. True, if it's just about pairs, then it might not be as fast as what you did here, but if it comes to tuplets of more than 2 numbers, I don't think there is much benefit of what you are trying to do here (although this is just a guess, I didn't actually benchmark it).