/projects/OG-Util/src/com/opengamma/util/tuple/Pair.java

https://github.com/gsteri1/OG-Platform · Java · 231 lines · 84 code · 23 blank · 124 comment · 5 complexity · 4eb82d01dc6acf6ebe97f0fd2f5a0183 MD5 · raw file

  1. /**
  2. * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
  3. *
  4. * Please see distribution for license.
  5. */
  6. package com.opengamma.util.tuple;
  7. import java.io.Serializable;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.Map;
  11. import org.apache.commons.lang.ObjectUtils;
  12. import org.apache.commons.lang.builder.CompareToBuilder;
  13. import com.opengamma.util.PublicAPI;
  14. /**
  15. * An immutable pair consisting of two elements.
  16. * <p>
  17. * This implementation refers to the elements as 'first' and 'second'.
  18. * The class also implements the {@code Map.Entry} interface where the key is 'first'
  19. * and the value is 'second'.
  20. * <p>
  21. * Although the implementation is immutable, there is no restriction on the objects
  22. * that may be stored. If mutable objects are stored in the pair, then the pair itself
  23. * effectively becomes mutable.
  24. *
  25. * @param <A> the first element type
  26. * @param <B> the second element type
  27. */
  28. @PublicAPI
  29. public abstract class Pair<A, B> implements Map.Entry<A, B>, Comparable<Pair<A, B>>, Serializable {
  30. /** Serialization version. */
  31. private static final long serialVersionUID = 1L;
  32. /**
  33. * Creates a pair of {@code Object}s inferring the types.
  34. *
  35. * @param <A> the first element type
  36. * @param <B> the second element type
  37. * @param first the first element, may be null
  38. * @param second the second element, may be null
  39. * @return a pair formed from the two parameters, not null
  40. */
  41. public static <A, B> ObjectsPair<A, B> of(A first, B second) {
  42. return new ObjectsPair<A, B>(first, second);
  43. }
  44. /**
  45. * Creates a pair of {@code Double}s.
  46. *
  47. * @param first the first element, may be null
  48. * @param second the second element, may be null
  49. * @return a pair formed from the two parameters, not null
  50. */
  51. public static ObjectsPair<Double, Double> of(Double first, double second) {
  52. return new ObjectsPair<Double, Double>(first, second);
  53. }
  54. /**
  55. * Creates a pair of {@code Double}s.
  56. *
  57. * @param first the first element, may be null
  58. * @param second the second element, may be null
  59. * @return a pair formed from the two parameters, not null
  60. */
  61. public static ObjectsPair<Double, Double> of(double first, Double second) {
  62. return new ObjectsPair<Double, Double>(first, second);
  63. }
  64. /**
  65. * Creates a pair of {@code double}s.
  66. *
  67. * @param first the first element, may be null
  68. * @param second the second element, may be null
  69. * @return a pair formed from the two parameters, not null
  70. */
  71. public static DoublesPair of(double first, double second) {
  72. return new DoublesPair(first, second);
  73. }
  74. /**
  75. * Creates a pair of {@code int} to {@code double}.
  76. *
  77. * @param first the first element, may be null
  78. * @param second the second element, may be null
  79. * @return a pair formed from the two parameters, not null
  80. */
  81. public static IntDoublePair of(int first, double second) {
  82. return new IntDoublePair(first, second);
  83. }
  84. /**
  85. * Creates a pair of {@code long} to {@code double}.
  86. *
  87. * @param first the first element, may be null
  88. * @param second the second element, may be null
  89. * @return a pair formed from the two parameters, not null
  90. */
  91. public static LongDoublePair of(long first, double second) {
  92. return new LongDoublePair(first, second);
  93. }
  94. /**
  95. * Constructs a pair.
  96. */
  97. protected Pair() {
  98. }
  99. //-------------------------------------------------------------------------
  100. /**
  101. * Gets the first element from this pair.
  102. * <p>
  103. * When treated as a key-value pair, this is the key.
  104. *
  105. * @return the first element, may be null
  106. */
  107. public abstract A getFirst();
  108. /**
  109. * Gets the second element from this pair.
  110. * <p>
  111. * When treated as a key-value pair, this is the value.
  112. *
  113. * @return the second element, may be null
  114. */
  115. public abstract B getSecond();
  116. /**
  117. * Gets the key from this pair.
  118. * <p>
  119. * This method implements the {@code Map.Entry} interface returning the
  120. * first element as the key.
  121. *
  122. * @return the first element as the key, may be null
  123. */
  124. @Override
  125. public A getKey() {
  126. return getFirst();
  127. }
  128. /**
  129. * Gets the value from this pair.
  130. * <p>
  131. * This method implements the {@code Map.Entry} interface returning the
  132. * second element as the value.
  133. *
  134. * @return the second element as the value, may be null
  135. */
  136. @Override
  137. public B getValue() {
  138. return getSecond();
  139. }
  140. /**
  141. * Throws {@code UnsupportedOperationException} as this class is immutable.
  142. *
  143. * @param value the new value, may be null
  144. * @return never
  145. */
  146. @Override
  147. public B setValue(B value) {
  148. throw new UnsupportedOperationException("Pair is immutable");
  149. }
  150. //-------------------------------------------------------------------------
  151. /**
  152. * Gets the elements from this pair as a list.
  153. * <p>
  154. * This method supports auto-casting as they is no way in generics to provide
  155. * a more specific type.
  156. *
  157. * @param <T> an auto-cast list type
  158. * @return the elements as a list, not null
  159. */
  160. @SuppressWarnings("unchecked")
  161. public <T> List<T> toList() {
  162. ArrayList<Object> list = new ArrayList<Object>();
  163. list.add(getFirst());
  164. list.add(getSecond());
  165. return (List<T>) list;
  166. }
  167. //-------------------------------------------------------------------------
  168. /**
  169. * Compares the pair based on the first element followed by the second element.
  170. * The types must be {@code Comparable}.
  171. *
  172. * @param other the other pair, not null
  173. * @return negative if this is less, zero if equal, positive if greater
  174. */
  175. @Override
  176. public int compareTo(Pair<A, B> other) {
  177. return new CompareToBuilder().append(getFirst(), other.getFirst())
  178. .append(getSecond(), other.getSecond()).toComparison();
  179. }
  180. @Override
  181. public boolean equals(Object obj) {
  182. // see Map.Entry API specification
  183. if (this == obj) {
  184. return true;
  185. }
  186. if (obj instanceof Map.Entry<?, ?>) {
  187. Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
  188. return ObjectUtils.equals(getKey(), other.getKey()) &&
  189. ObjectUtils.equals(getValue(), other.getValue());
  190. }
  191. return false;
  192. }
  193. @Override
  194. public int hashCode() {
  195. // see Map.Entry API specification
  196. return (getKey() == null ? 0 : getKey().hashCode()) ^
  197. (getValue() == null ? 0 : getValue().hashCode());
  198. }
  199. @Override
  200. public String toString() {
  201. return new StringBuilder()
  202. .append("[")
  203. .append(getFirst())
  204. .append(", ")
  205. .append(getSecond())
  206. .append("]").toString();
  207. }
  208. }