1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.comparators;
  17. import java.io.Serializable;
  18. import java.util.Comparator;
  19. /**
  20. * A {@link Comparator} for {@link Boolean} objects that can sort either
  21. * true or false first.
  22. * <p>
  23. * @see #getTrueFirstComparator()
  24. * @see #getFalseFirstComparator()
  25. * @see #getBooleanComparator(boolean)
  26. *
  27. * @since Commons Collections 3.0
  28. * @version $Revision: 1.14 $ $Date: 2004/05/16 11:56:47 $
  29. *
  30. * @author Rodney Waldhoff
  31. */
  32. public final class BooleanComparator implements Comparator, Serializable {
  33. /** Serialization version. */
  34. private static final long serialVersionUID = 1830042991606340609L;
  35. /** Constant "true first" reference. */
  36. private static final BooleanComparator TRUE_FIRST = new BooleanComparator(true);
  37. /** Constant "false first" reference. */
  38. private static final BooleanComparator FALSE_FIRST = new BooleanComparator(false);
  39. /** <code>true</code> iff <code>true</code> values sort before <code>false</code> values. */
  40. private boolean trueFirst = false;
  41. //-----------------------------------------------------------------------
  42. /**
  43. * Returns a BooleanComparator instance that sorts
  44. * <code>true</code> values before <code>false</code> values.
  45. * <p />
  46. * Clients are encouraged to use the value returned from
  47. * this method instead of constructing a new instance
  48. * to reduce allocation and garbage collection overhead when
  49. * multiple BooleanComparators may be used in the same
  50. * virtual machine.
  51. *
  52. * @return the true first singleton BooleanComparator
  53. */
  54. public static BooleanComparator getTrueFirstComparator() {
  55. return TRUE_FIRST;
  56. }
  57. /**
  58. * Returns a BooleanComparator instance that sorts
  59. * <code>false</code> values before <code>true</code> values.
  60. * <p />
  61. * Clients are encouraged to use the value returned from
  62. * this method instead of constructing a new instance
  63. * to reduce allocation and garbage collection overhead when
  64. * multiple BooleanComparators may be used in the same
  65. * virtual machine.
  66. *
  67. * @return the false first singleton BooleanComparator
  68. */
  69. public static BooleanComparator getFalseFirstComparator() {
  70. return FALSE_FIRST;
  71. }
  72. /**
  73. * Returns a BooleanComparator instance that sorts
  74. * <code><i>trueFirst</i></code> values before
  75. * <code>!<i>trueFirst</i></code> values.
  76. * <p />
  77. * Clients are encouraged to use the value returned from
  78. * this method instead of constructing a new instance
  79. * to reduce allocation and garbage collection overhead when
  80. * multiple BooleanComparators may be used in the same
  81. * virtual machine.
  82. *
  83. * @param trueFirst when <code>true</code>, sort
  84. * <code>true</code> <code>Boolean</code>s before <code>false</code>
  85. * @return a singleton BooleanComparator instance
  86. */
  87. public static BooleanComparator getBooleanComparator(boolean trueFirst) {
  88. return trueFirst ? TRUE_FIRST : FALSE_FIRST;
  89. }
  90. //-----------------------------------------------------------------------
  91. /**
  92. * Creates a <code>BooleanComparator</code> that sorts
  93. * <code>false</code> values before <code>true</code> values.
  94. * <p>
  95. * Equivalent to {@link #BooleanComparator(boolean) BooleanComparator(false)}.
  96. * <p>
  97. * Please use the static factory instead whenever possible.
  98. */
  99. public BooleanComparator() {
  100. this(false);
  101. }
  102. /**
  103. * Creates a <code>BooleanComparator</code> that sorts
  104. * <code><i>trueFirst</i></code> values before
  105. * <code>!<i>trueFirst</i></code> values.
  106. * <p>
  107. * Please use the static factories instead whenever possible.
  108. *
  109. * @param trueFirst when <code>true</code>, sort
  110. * <code>true</code> boolean values before <code>false</code>
  111. */
  112. public BooleanComparator(boolean trueFirst) {
  113. this.trueFirst = trueFirst;
  114. }
  115. //-----------------------------------------------------------------------
  116. /**
  117. * Compares two arbitrary Objects.
  118. * When both arguments are <code>Boolean</code>, this method is equivalent to
  119. * {@link #compare(Boolean,Boolean) compare((Boolean)<i>obj1</i>,(Boolean)<i>obj2</i>)}.
  120. * When either argument is not a <code>Boolean</code>, this methods throws
  121. * a {@link ClassCastException}.
  122. *
  123. * @param obj1 the first object to compare
  124. * @param obj2 the second object to compare
  125. * @return negative if obj1 is less, positive if greater, zero if equal
  126. * @throws ClassCastException when either argument is not <code>Boolean</code>
  127. */
  128. public int compare(Object obj1, Object obj2) {
  129. return compare((Boolean)obj1, (Boolean)obj2);
  130. }
  131. /**
  132. * Compares two non-<code>null</code> <code>Boolean</code> objects
  133. * according to the value of {@link #trueFirst}.
  134. *
  135. * @param b1 the first boolean to compare
  136. * @param b2 the second boolean to compare
  137. * @return negative if obj1 is less, positive if greater, zero if equal
  138. * @throws NullPointerException when either argument <code>null</code>
  139. */
  140. public int compare(Boolean b1, Boolean b2) {
  141. boolean v1 = b1.booleanValue();
  142. boolean v2 = b2.booleanValue();
  143. return (v1 ^ v2) ? ( (v1 ^ trueFirst) ? 1 : -1 ) : 0;
  144. }
  145. //-----------------------------------------------------------------------
  146. /**
  147. * Implement a hash code for this comparator that is consistent with
  148. * {@link #equals(Object) equals}.
  149. *
  150. * @return a hash code for this comparator.
  151. */
  152. public int hashCode() {
  153. int hash = "BooleanComparator".hashCode();
  154. return trueFirst ? -1 * hash : hash;
  155. }
  156. /**
  157. * Returns <code>true</code> iff <i>that</i> Object is
  158. * is a {@link Comparator} whose ordering is known to be
  159. * equivalent to mine.
  160. * <p>
  161. * This implementation returns <code>true</code>
  162. * iff <code><i>that</i></code> is a {@link BooleanComparator}
  163. * whose {@link #trueFirst} value is equal to mine.
  164. *
  165. * @param object the object to compare to
  166. * @return true if equal
  167. */
  168. public boolean equals(Object object) {
  169. return (this == object) ||
  170. ((object instanceof BooleanComparator) &&
  171. (this.trueFirst == ((BooleanComparator)object).trueFirst));
  172. }
  173. //-----------------------------------------------------------------------
  174. /**
  175. * Returns <code>true</code> iff
  176. * I sort <code>true</code> values before
  177. * <code>false</code> values. In other words,
  178. * returns <code>true</code> iff
  179. * {@link #compare(Boolean,Boolean) compare(Boolean.FALSE,Boolean.TRUE)}
  180. * returns a positive value.
  181. *
  182. * @return the trueFirst flag
  183. */
  184. public boolean sortsTrueFirst() {
  185. return trueFirst;
  186. }
  187. }