001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.comparators; 018 019import java.io.Serializable; 020import java.util.Comparator; 021 022/** 023 * A {@link Comparator} for {@link Boolean} objects that can sort either 024 * true or false first. 025 * 026 * @see #getTrueFirstComparator() 027 * @see #getFalseFirstComparator() 028 * @see #booleanComparator(boolean) 029 * @since 3.0 030 */ 031public final class BooleanComparator implements Comparator<Boolean>, Serializable { 032 033 /** Serialization version. */ 034 private static final long serialVersionUID = 1830042991606340609L; 035 036 /** Constant "true first" reference. */ 037 private static final BooleanComparator TRUE_FIRST = new BooleanComparator(true); 038 039 /** Constant "false first" reference. */ 040 private static final BooleanComparator FALSE_FIRST = new BooleanComparator(false); 041 042 /** 043 * Returns a BooleanComparator instance that sorts 044 * {@code <em>trueFirst</em>} values before 045 * {@code !<em>trueFirst</em>} values. 046 * <p> 047 * Clients are encouraged to use the value returned from 048 * this method instead of constructing a new instance 049 * to reduce allocation and garbage collection overhead when 050 * multiple BooleanComparators may be used in the same 051 * virtual machine. 052 * </p> 053 * 054 * @param trueFirst when {@code true}, sort 055 * {@code true} {@code Boolean}s before {@code false} 056 * @return a singleton BooleanComparator instance 057 * @since 4.0 058 */ 059 public static BooleanComparator booleanComparator(final boolean trueFirst) { 060 return trueFirst ? TRUE_FIRST : FALSE_FIRST; 061 } 062 063 /** 064 * Returns a BooleanComparator instance that sorts 065 * {@code false} values before {@code true} values. 066 * <p> 067 * Clients are encouraged to use the value returned from 068 * this method instead of constructing a new instance 069 * to reduce allocation and garbage collection overhead when 070 * multiple BooleanComparators may be used in the same 071 * virtual machine. 072 * </p> 073 * 074 * @return the false first singleton BooleanComparator 075 */ 076 public static BooleanComparator getFalseFirstComparator() { 077 return FALSE_FIRST; 078 } 079 080 /** 081 * Returns a BooleanComparator instance that sorts 082 * {@code true} values before {@code false} values. 083 * <p> 084 * Clients are encouraged to use the value returned from 085 * this method instead of constructing a new instance 086 * to reduce allocation and garbage collection overhead when 087 * multiple BooleanComparators may be used in the same 088 * virtual machine. 089 * </p> 090 * 091 * @return the true first singleton BooleanComparator 092 */ 093 public static BooleanComparator getTrueFirstComparator() { 094 return TRUE_FIRST; 095 } 096 097 /** {@code true} iff {@code true} values sort before {@code false} values. */ 098 private final boolean trueFirst; 099 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 !<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}