Java Needs to Get a Pair (and a Triple...), Page 3
Is It Complete?
Yes, and no! This class is in use at Navigenics where it performs well. Doubtless there are other similar implementations all over other Java applications out there, which probably offer the same feature set and are as useful. Is it complete then? From a "we can use it as it is for most foreseeable needs", then yes it is complete. From a "will it be the only pair we will ever need" then possibly not.
For example, Pairs represented by this class cannot be compared. I thought about adding a compareTo() method and making it Comparable but here you start to hit the complexity that even simple general class design brings up. In very general usage, what is the correct behavior for it? It's easy to say that you compare the first value, and if they are equal, compare the second value. This is likely the most consistent behavior, but is it right for every usage of Pair? You would also need to check if the classes being compared are themselves comparable, and if not use what? The object reference comparison?
I sidestepped the issue. I know enough from writing that less is usually more, or as my thesis tutor used to say: "Omit Unnecessary Words". If someone wants their Pair usage to be comparable, they can supply a comparator to do it. After all, Lists are not Comparable in the Java SE libraries either.
Pair also isn't Cloneable, and this would be easy enough to add. Perhaps it should be, but it's also really easy to clone a Pair (just create a new Pair of the first and second from another Pair). It seems unnecessary.
So, yes I would claim that this is complete enough. Simple wins every time in my opinion.
What About Triple?
The bigger question here is where do you stop.
If Pair is twice as good as a single return type, surely Triple is three times as good, right?
In truth I bekieve there is a reasonable case for a triple implementation (I have one in my codebase) since I can see use cases where I want to return three objects instead of two. Some libraries implement a Quadruple as well, but I would argue (strictly from my own opinion) that four or more returns is less common, and when you get to returning above three objects, perhaps it is time to implement a custom lightweight transfer object anyway, if only to remember which object is in what position (e.g. was name the third or fourth object now?)
Other people I have spoken to claim that Pair is all you need, since you can make a triple like this:
Pair<String, Pair<Integer, Date>>
But this leads to uses like the following:
Pair<String, Pair<Integer, Date>> triple = methodReturningTriple(); System.out.println(triple.first, triple.second.first, triple.second.second);
Now I don't know about you, but I have some style issues with references like triple.second.second from a readability perspective compared with a simple triple.third. Not to mention the definition Triple<String, Integer, Date> is a lot cleaner than Pair<String, Pair<Integer, Date>>.
The implementation of Triple is simple enough - take the Pair class and add a third attribute with a generic class C. Adjust the equals, hashCode, of and toString methods plus the constructor accordingly, and you are done.
Creating a Pair class for Java is hardly in the realm of rocket science, but even here, in the implementation of a simple generalized library class, one which requires no language changes to Java and one with a very small feature list, some questions still exist. Generality are troublesome. Imagine then the problems facing some of the questions about the "small" language changes to be added to Java 7 with Project Coin. I do not envy the work ahead for the language designers and would-be language designers in implementing these changes without (hopefully) disrupting anything important in the general uses of the language.
Still, I believe the Pair class described here is at least a good starting point for a standardized Pair implementation in the SE libraries. I hope this addition will be in the Java 7 release. Even though it is really a poor substitute for the Tuples available in other languages, the inclusion of a standard Pair (and maybe Triple) will hopefully provide a great deal of utility, an improvement in readability and removal of a lot of boilerplate code, all of which are aims for the project Coin small language changes, and all this without needing to change the language at all.
Finally, if you dispute the need for a standardized Pair class, just take a look at the multitude of implementations already out there in the open source world (and probably many times more in proprietary code bases).
Finally, I would like to say thanks in particular to Tomas Zezula, a NetBeans engineer whose Pair implementation in the open source NetBeans codebase provided valuable considerations in the construction of this article. Interestingly Pair appears (as far as I can tell) in 11 different locations in the NetBeans codebase alone. Yes, I would say one is needed in the Java SE libraries...
About the Author
Dick Wall is a Software Engineer for Navigenics, Inc. A bay area startup specializing in genetic personalized medicine services at http://www.navigenics.com and is also co-host of the Java Posse podcast , a developer centric podcast all about the news, happenings and technology in the Java development world.