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.lang3.compare; 018 019import java.util.function.Predicate; 020 021import org.apache.commons.lang3.ObjectUtils; 022 023/** 024 * Utility library to provide helper methods for translating {@link Comparable#compareTo} result into a boolean. 025 * 026 * <p>Example: {@code boolean x = is(myComparable).lessThanOrEqualTo(otherComparable)}</p> 027 * 028 * <p>#ThreadSafe#</p> 029 * 030 * @since 3.10 031 */ 032public class ComparableUtils { 033 034 /** 035 * Provides access to the available methods 036 * 037 * @param <A> the type of objects that this object may be compared against. 038 */ 039 public static class ComparableCheckBuilder<A extends Comparable<A>> { 040 041 private final A a; 042 043 private ComparableCheckBuilder(final A a) { 044 this.a = a; 045 } 046 047 /** 048 * Checks if {@code [b <= a <= c]} or {@code [b >= a >= c]} where the {@code a} is object passed to {@link #is}. 049 * 050 * @param b the object to compare to the base object 051 * @param c the object to compare to the base object 052 * @return true if the base object is between b and c 053 */ 054 public boolean between(final A b, final A c) { 055 return betweenOrdered(b, c) || betweenOrdered(c, b); 056 } 057 058 /** 059 * Checks if {@code (b < a < c)} or {@code (b > a > c)} where the {@code a} is object passed to {@link #is}. 060 * 061 * @param b the object to compare to the base object 062 * @param c the object to compare to the base object 063 * @return true if the base object is between b and c and not equal to those 064 */ 065 public boolean betweenExclusive(final A b, final A c) { 066 return betweenOrderedExclusive(b, c) || betweenOrderedExclusive(c, b); 067 } 068 069 private boolean betweenOrdered(final A b, final A c) { 070 return greaterThanOrEqualTo(b) && lessThanOrEqualTo(c); 071 } 072 073 private boolean betweenOrderedExclusive(final A b, final A c) { 074 return greaterThan(b) && lessThan(c); 075 } 076 077 /** 078 * Checks if the object passed to {@link #is} is equal to {@code b} 079 * 080 * @param b the object to compare to the base object 081 * @return true if the value returned by {@link Comparable#compareTo} is equal to {@code 0} 082 */ 083 public boolean equalTo(final A b) { 084 return a.compareTo(b) == 0; 085 } 086 087 /** 088 * Checks if the object passed to {@link #is} is greater than {@code b} 089 * 090 * @param b the object to compare to the base object 091 * @return true if the value returned by {@link Comparable#compareTo} is greater than {@code 0} 092 */ 093 public boolean greaterThan(final A b) { 094 return a.compareTo(b) > 0; 095 } 096 097 /** 098 * Checks if the object passed to {@link #is} is greater than or equal to {@code b} 099 * 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}