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.lang3.compare; 18 19 import java.util.function.Predicate; 20 21 import org.apache.commons.lang3.ObjectUtils; 22 23 /** 24 * Utility library to provide helper methods for translating {@link Comparable#compareTo} result into a boolean. 25 * 26 * <p>Example: {@code boolean x = is(myComparable).lessThanOrEqualTo(otherComparable)}</p> 27 * 28 * <p>#ThreadSafe#</p> 29 * 30 * @since 3.10 31 */ 32 public class ComparableUtils { 33 34 /** 35 * Provides access to the available methods 36 * 37 * @param <A> the type of objects that this object may be compared against. 38 */ 39 public static class ComparableCheckBuilder<A extends Comparable<A>> { 40 41 private final A a; 42 43 private ComparableCheckBuilder(final A a) { 44 this.a = a; 45 } 46 47 /** 48 * Checks if {@code [b <= a <= c]} or {@code [b >= a >= c]} where the {@code a} is object passed to {@link #is}. 49 * 50 * @param b the object to compare to the base object 51 * @param c the object to compare to the base object 52 * @return true if the base object is between b and c 53 */ 54 public boolean between(final A b, final A c) { 55 return betweenOrdered(b, c) || betweenOrdered(c, b); 56 } 57 58 /** 59 * Checks if {@code (b < a < c)} or {@code (b > a > c)} where the {@code a} is object passed to {@link #is}. 60 * 61 * @param b the object to compare to the base object 62 * @param c the object to compare to the base object 63 * @return true if the base object is between b and c and not equal to those 64 */ 65 public boolean betweenExclusive(final A b, final A c) { 66 return betweenOrderedExclusive(b, c) || betweenOrderedExclusive(c, b); 67 } 68 69 private boolean betweenOrdered(final A b, final A c) { 70 return greaterThanOrEqualTo(b) && lessThanOrEqualTo(c); 71 } 72 73 private boolean betweenOrderedExclusive(final A b, final A c) { 74 return greaterThan(b) && lessThan(c); 75 } 76 77 /** 78 * Checks if the object passed to {@link #is} is equal to {@code b} 79 * 80 * @param b the object to compare to the base object 81 * @return true if the value returned by {@link Comparable#compareTo} is equal to {@code 0} 82 */ 83 public boolean equalTo(final A b) { 84 return a.compareTo(b) == 0; 85 } 86 87 /** 88 * Checks if the object passed to {@link #is} is greater than {@code b} 89 * 90 * @param b the object to compare to the base object 91 * @return true if the value returned by {@link Comparable#compareTo} is greater than {@code 0} 92 */ 93 public boolean greaterThan(final A b) { 94 return a.compareTo(b) > 0; 95 } 96 97 /** 98 * Checks if the object passed to {@link #is} is greater than or equal to {@code b} 99 * 100 * @param b the object to compare to the base object 101 * @return true if the value returned by {@link Comparable#compareTo} is greater than or equal to {@code 0} 102 */ 103 public boolean greaterThanOrEqualTo(final A b) { 104 return a.compareTo(b) >= 0; 105 } 106 107 /** 108 * Checks if the object passed to {@link #is} is less than {@code b} 109 * 110 * @param b the object to compare to the base object 111 * @return true if the value returned by {@link Comparable#compareTo} is less than {@code 0} 112 */ 113 public boolean lessThan(final A b) { 114 return a.compareTo(b) < 0; 115 } 116 117 /** 118 * Checks if the object passed to {@link #is} is less than or equal to {@code b} 119 * 120 * @param b the object to compare to the base object 121 * @return true if the value returned by {@link Comparable#compareTo} is less than or equal to {@code 0} 122 */ 123 public boolean lessThanOrEqualTo(final A b) { 124 return a.compareTo(b) <= 0; 125 } 126 } 127 128 /** 129 * Checks if {@code [b <= a <= c]} or {@code [b >= a >= c]} where the {@code a} is the tested object. 130 * 131 * @param b the object to compare to the tested object 132 * @param c the object to compare to the tested object 133 * @param <A> type of the test object 134 * @return a predicate for true if the tested object is between b and c 135 */ 136 public static <A extends Comparable<A>> Predicate<A> between(final A b, final A c) { 137 return a -> is(a).between(b, c); 138 } 139 140 /** 141 * Checks if {@code (b < a < c)} or {@code (b > a > c)} where the {@code a} is the tested object. 142 * 143 * @param b the object to compare to the tested object 144 * @param c the object to compare to the tested object 145 * @param <A> type of the test object 146 * @return a predicate for true if the tested object is between b and c and not equal to those 147 */ 148 public static <A extends Comparable<A>> Predicate<A> betweenExclusive(final A b, final A c) { 149 return a -> is(a).betweenExclusive(b, c); 150 } 151 152 /** 153 * Checks if the tested object is greater than or equal to {@code b} 154 * 155 * @param b the object to compare to the tested object 156 * @param <A> type of the test object 157 * @return a predicate for true if the value returned by {@link Comparable#compareTo} 158 * is greater than or equal to {@code 0} 159 */ 160 public static <A extends Comparable<A>> Predicate<A> ge(final A b) { 161 return a -> is(a).greaterThanOrEqualTo(b); 162 } 163 164 /** 165 * Checks if the tested object is greater than {@code b} 166 * 167 * @param b the object to compare to the tested object 168 * @param <A> type of the test object 169 * @return a predicate for true if the value returned by {@link Comparable#compareTo} is greater than {@code 0} 170 */ 171 public static <A extends Comparable<A>> Predicate<A> gt(final A b) { 172 return a -> is(a).greaterThan(b); 173 } 174 175 /** 176 * Provides access to the available methods 177 * 178 * @param a base object in the further comparison 179 * @param <A> type of the base object 180 * @return a builder object with further methods 181 */ 182 public static <A extends Comparable<A>> ComparableCheckBuilder<A> is(final A a) { 183 return new ComparableCheckBuilder<>(a); 184 } 185 186 /** 187 * Checks if the tested object is less than or equal to {@code b} 188 * 189 * @param b the object to compare to the tested object 190 * @param <A> type of the test object 191 * @return a predicate for true if the value returned by {@link Comparable#compareTo} 192 * is less than or equal to {@code 0} 193 */ 194 public static <A extends Comparable<A>> Predicate<A> le(final A b) { 195 return a -> is(a).lessThanOrEqualTo(b); 196 } 197 198 /** 199 * Checks if the tested object is less than {@code b} 200 * 201 * @param b the object to compare to the tested object 202 * @param <A> type of the test object 203 * @return a predicate for true if the value returned by {@link Comparable#compareTo} is less than {@code 0} 204 */ 205 public static <A extends Comparable<A>> Predicate<A> lt(final A b) { 206 return a -> is(a).lessThan(b); 207 } 208 209 /** 210 * Returns the greater of two {@link Comparable} values, ignoring null. 211 * <p> 212 * For three or more values, use {@link ObjectUtils#max(Comparable...)}. 213 * </p> 214 * 215 * @param <A> Type of what we are comparing. 216 * @param comparable1 the first comparable, may be null. 217 * @param comparable2 the second comparable, may be null. 218 * @return the largest of {@code comparable1} and {@code comparable2}. 219 * @see ObjectUtils#max(Comparable...) 220 * @since 3.13.0 221 */ 222 public static <A extends Comparable<A>> A max(final A comparable1, final A comparable2) { 223 return ObjectUtils.compare(comparable1, comparable2, false) > 0 ? comparable1 : comparable2; 224 } 225 226 /** 227 * Returns the lesser of two {@link Comparable} values, ignoring null. 228 * <p> 229 * For three or more values, use {@link ObjectUtils#min(Comparable...)}. 230 * </p> 231 * 232 * @param <A> Type of what we are comparing. 233 * @param comparable1 the first comparable, may be null. 234 * @param comparable2 the second comparable, may be null. 235 * @return the smallest of {@code comparable1} and {@code comparable2}. 236 * @see ObjectUtils#min(Comparable...) 237 * @since 3.13.0 238 */ 239 public static <A extends Comparable<A>> A min(final A comparable1, final A comparable2) { 240 return ObjectUtils.compare(comparable1, comparable2, true) < 0 ? comparable1 : comparable2; 241 } 242 243 private ComparableUtils() { 244 // empty 245 } 246 }