A Generic Pair in Java

Tagged:

The Java language lacks a tuple type, so when you need to return more than one object from a method call, you need to create a value object to hold the pieces. As noted in a recent Java Posse Podcast, Java has no Pair object in its standard libraries. Here's our implementation of a reusable Pair object, built with Java generics.

Hopefully our code, below, is documented well enough for use as is. But a few points are worth mentioning:

  • Nulls are not permitted for either the left or right side of the pair.
  • There are no setters for the left and right variables, so this object is immutable. We favor immutability in such objects, as they guarantee threadsafety.
  • We use the Jakarta project's Commons Lang package for hash code building. It's surprisingly difficult to write a really good hash function, so we exploit Jakarta's labors here.
  • Pairs are not comparable so as not to require comparability on either side.

Without further ado, Ideograph's generic Pair:

  1. package com.ideograph.lib.util;
  2.  
  3. import org.apache.commons.lang.Validate;
  4. import org.apache.commons.lang.builder.EqualsBuilder;
  5. import org.apache.commons.lang.builder.HashCodeBuilder;
  6.  
  7. public class Pair<L, R> {
  8. private final L left;
  9. private final R right;
  10.  
  11. /**
  12. * Constructor. Accepts two objects and constructs a pair.
  13. *Neither can be null.
  14. *
  15. * @param left
  16. * The left object
  17. * @param right
  18. * The right object
  19. */
  20. public Pair(L left, R right) {
  21. Validate.notNull(left);
  22. this.left = left;
  23. Validate.notNull(right);
  24. this.right = right;
  25. }
  26.  
  27. /**
  28. * Returns the left item of the pair.
  29. *
  30. * @return the left item
  31. */
  32. public L getLeft() {
  33. return left;
  34. }
  35.  
  36. /**
  37. * Returns the right item of the pair.
  38. *
  39. * @return the left item
  40. */
  41. public R getRight() {
  42. return right;
  43. }
  44.  
  45. /**
  46. * Returns true iff the the two pairs are equal.
  47. *
  48. * @param other
  49. * some other pair
  50. * @return true if equal
  51. */
  52. @Override
  53. public boolean equals(Object other) {
  54. if (other == this)
  55. return true;
  56. if (!(other instanceof Pair))
  57. return false;
  58. Pair<?, ?> that = (Pair<?, ?>) other;
  59. return new EqualsBuilder().
  60. append(this.left, that.left).
  61. append(this.right, that.right).
  62. isEquals();
  63. }
  64.  
  65. /**
  66. * Returns a hash code for this pair
  67. *
  68. * @return the hash code
  69. */
  70. @Override
  71. public int hashCode() {
  72. return new HashCodeBuilder().
  73. append(this.left).
  74. append(this.right).
  75. toHashCode();
  76. }
  77.  
  78. /**
  79. * Returns the string form of this pair: "(left,right)"
  80. */
  81. @Override
  82. public String toString() {
  83. StringBuilder sb = new StringBuilder("(");
  84. sb.append(left.toString());
  85. sb.append(",");
  86. sb.append(right.toString());
  87. sb.append(")");
  88. return sb.toString();
  89. }
  90. }

Client Login