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