An interesting discussion popped up this week about whether it would be useful to add a java.util.Pair in JDK 7. This has been requested many times in the past and I know I’ve heard some talk about it on the Java Posse as well. Pair is of course a special case for two elements and suggests possibly a Triple or Tuple as well, although Pair seems vastly more common than either of those.
I believe by far the most common use case for a Pair is to return multiple values from a single function. Dick Wall made a case for Pair in his Funky Java talk at Devoxx. I certainly found a number of Pair implementors and fans on Twitter. Joe Darcy seemed to think the large number of Pairs in the wild were an indication that having a single version in the JDK might be better than many different implementations and he submitted a strawman version.
It was rightly pointed out that both mutable (AbstractMap.SimpleEntry<K,V>) and immutable (AbstractMap.SimpleImmutableEntry<K,V>) implementations exist in java.util now although they are obviously a bit buried in their current incarnation and probably even less usefully named than Pair.
I believe the major dissent focuses on how Pair is a poor class name and has poor method names. “Pair” does not name the thing you are returning in any useful way other than telling you it’s “two things”. The methods of Pair are usually also generic as in “getA” or “getFirst”. If there is a real meaning behind putting those values together, then there is probably also a better conceptual name to use instead. If the two values really aren’t related in any useful way, then the code is probably poorly factored to start with due to a bad separation of concerns.
Bob Lee made a strong plea against Pair (with support from Mark Reinhold) as it would encourage the proliferation of bad code. Kevin Bourrillion and Josh Bloch were also arguing against Pair for JDK 7 but thought that a more general solution of n-arg value types might be a useful thing to attack in a future JDK.
I must admit that I have created and used a Pair at least once in the past, but it made me feel dirty and I eventually refactored it away. Interestingly, I’ve seen the same issue even in Clojure. When I’ve written code that returns a seq that I must pick apart with
second, etc, it feels equally dirty. Working with collections of homogenous elements is great but as soon as positional behavior matters, I feel uncomfortable. In Clojure, it can still be ok, but only if the scope happens within a single function and even then I prefer to use destructuring rather than
In the end, I guess my own personal view is that the case for Pair is weak – I certainly don’t think it’s necessary.