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 * https://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 * Helper translating {@link Comparable#compareTo} results to booleans. 025 * 026 * <p> 027 * Example: {@code boolean x = ComparableUtils.is(myComparable).lessThanOrEqualTo(otherComparable)} 028 * </p> 029 * 030 * <p> 031 * #ThreadSafe# 032 * </p> 033 * 034 * @since 3.10 035 */ 036public class ComparableUtils { 037 038 /** 039 * Compares objects of a given generic type {@code A}. 040 * 041 * @param <A> The type of objects that this object may be compared against. 042 */ 043 public static class ComparableCheckBuilder<A extends Comparable<A>> { 044 045 private final A a; 046 047 private ComparableCheckBuilder(final A a) { 048 this.a = a; 049 } 050 051 /** 052 * Tests if {@code [b <= a <= c]} or {@code [b >= a >= c]} where the {@code a} is object passed to {@link #is}. 053 * 054 * @param b The object to compare to the base object 055 * @param c The object to compare to the base object 056 * @return true if the base object is between b and c 057 */ 058 public boolean between(final A b, final A c) { 059 return betweenOrdered(b, c) || betweenOrdered(c, b); 060 } 061 062 /** 063 * Tests if {@code (b < a < c)} or {@code (b > a > c)} where the {@code a} is object passed to {@link #is}. 064 * 065 * @param b The object to compare to the base object 066 * @param c The object to compare to the base object 067 * @return true if the base object is between b and c and not equal to those 068 */ 069 public boolean betweenExclusive(final A b, final A c) { 070 return betweenOrderedExclusive(b, c) || betweenOrderedExclusive(c, b); 071 } 072 073 private boolean betweenOrdered(final A b, final A c) { 074 return greaterThanOrEqualTo(b) && lessThanOrEqualTo(c); 075 } 076 077 private boolean betweenOrderedExclusive(final A b, final A c) { 078 return greaterThan(b) && lessThan(c); 079 } 080 081 /** 082 * Tests if the object passed to {@link #is} is equal to {@code b} 083 * 084 * @param b The object to compare to the base object 085 * @return true if the value returned by {@link Comparable#compareTo} is equal to {@code 0} 086 */ 087 public boolean equalTo(final A b) { 088 return a != null && a.compareTo(b) == 0; 089 } 090 091 /** 092 * Tests if the object passed to {@link #is} is greater than {@code b} 093 * 094 * @param b The object to compare to the base object 095 * @return true if the value returned by {@link Comparable#compareTo} is greater than {@code 0} 096 */ 097 public boolean greaterThan(final A b) { 098 return a != null && a.compareTo(b) > 0; 099 } 100 101 /** 102 * Tests if the object passed to {@link #is} is greater than or equal to {@code b} 103 * 104 * @param b The object to compare to the base object 105 * @return true if the value returned by {@link Comparable#compareTo} is greater than or equal to {@code 0} 106 */ 107 public boolean greaterThanOrEqualTo(final A b) { 108 return a != null && a.compareTo(b) >= 0; 109 } 110 111 /** 112 * Tests if the object passed to {@link #is} is less than {@code b} 113 * 114 * @param b The object to compare to the base object 115 * @return true if the value returned by {@link Comparable#compareTo} is less than {@code 0} 116 */ 117 public boolean lessThan(final A b) { 118 return a != null && a.compareTo(b) < 0; 119 } 120 121 /** 122 * Tests if the object passed to {@link #is} is less than or equal to {@code b} 123 * 124 * @param b The object to compare to the base object 125 * @return true if the value returned by {@link Comparable#compareTo} is less than or equal to {@code 0} 126 */ 127 public boolean lessThanOrEqualTo(final A b) { 128 return a != null && a.compareTo(b) <= 0; 129 } 130 } 131 132 /** 133 * Creates a predicate to test if {@code [b <= a <= c]} or {@code [b >= a >= c]} where the {@code a} is the tested object. 134 * 135 * @param b The object to compare to the tested object 136 * @param c The object to compare to the tested object 137 * @param <A> type of the test object 138 * @return A predicate for true if the tested object is between b and c 139 */ 140 public static <A extends Comparable<A>> Predicate<A> between(final A b, final A c) { 141 return a -> is(a).between(b, c); 142 } 143 144 /** 145 * Creates a predicate to test if {@code (b < a < c)} or {@code (b > a > c)} where the {@code a} is the tested object. 146 * 147 * @param b The object to compare to the tested object 148 * @param c The object to compare to the tested object 149 * @param <A> type of the test object 150 * @return A predicate for true if the tested object is between b and c and not equal to those 151 */ 152 public static <A extends Comparable<A>> Predicate<A> betweenExclusive(final A b, final A c) { 153 return a -> is(a).betweenExclusive(b, c); 154 } 155 156 /** 157 * Creates a predicate to test if the tested object is greater than or equal to {@code b} 158 * 159 * @param b The object to compare to the tested object 160 * @param <A> type of the test object 161 * @return A predicate for true if the value returned by {@link Comparable#compareTo} 162 * is greater than or equal to {@code 0} 163 */ 164 public static <A extends Comparable<A>> Predicate<A> ge(final A b) { 165 return a -> is(a).greaterThanOrEqualTo(b); 166 } 167 168 /** 169 * Creates a predicate to test if the tested object is greater than {@code b} 170 * 171 * @param b The object to compare to the tested object 172 * @param <A> type of the test object 173 * @return A predicate for true if the value returned by {@link Comparable#compareTo} is greater than {@code 0} 174 */ 175 public static <A extends Comparable<A>> Predicate<A> gt(final A b) { 176 return a -> is(a).greaterThan(b); 177 } 178 179 /** 180 * Creates a new {@link ComparableCheckBuilder}. 181 * 182 * @param a base object in the further comparison 183 * @param <A> type of the base object 184 * @return A builder object with further methods 185 */ 186 public static <A extends Comparable<A>> ComparableCheckBuilder<A> is(final A a) { 187 return new ComparableCheckBuilder<>(a); 188 } 189 190 /** 191 * Creates a predicate to test if the tested object is less than or equal to {@code b} 192 * 193 * @param b The object to compare to the tested object 194 * @param <A> type of the test object 195 * @return A predicate for true if the value returned by {@link Comparable#compareTo} 196 * is less than or equal to {@code 0} 197 */ 198 public static <A extends Comparable<A>> Predicate<A> le(final A b) { 199 return a -> is(a).lessThanOrEqualTo(b); 200 } 201 202 /** 203 * Creates a predicate to test if the tested object is less than {@code b} 204 * 205 * @param b The object to compare to the tested object 206 * @param <A> type of the test object 207 * @return A predicate for true if the value returned by {@link Comparable#compareTo} is less than {@code 0} 208 */ 209 public static <A extends Comparable<A>> Predicate<A> lt(final A b) { 210 return a -> is(a).lessThan(b); 211 } 212 213 /** 214 * Returns the greater of two {@link Comparable} values, ignoring null. 215 * <p> 216 * For three or more values, use {@link ObjectUtils#max(Comparable...)}. 217 * </p> 218 * 219 * @param <A> Type of what we are comparing. 220 * @param comparable1 The first comparable, may be null. 221 * @param comparable2 The second comparable, may be null. 222 * @return The largest of {@code comparable1} and {@code comparable2}. 223 * @see ObjectUtils#max(Comparable...) 224 * @since 3.13.0 225 */ 226 public static <A extends Comparable<A>> A max(final A comparable1, final A comparable2) { 227 return ObjectUtils.compare(comparable1, comparable2, false) > 0 ? comparable1 : comparable2; 228 } 229 230 /** 231 * Returns the lesser of two {@link Comparable} values, ignoring null. 232 * <p> 233 * For three or more values, use {@link ObjectUtils#min(Comparable...)}. 234 * </p> 235 * 236 * @param <A> Type of what we are comparing. 237 * @param comparable1 The first comparable, may be null. 238 * @param comparable2 The second comparable, may be null. 239 * @return The smallest of {@code comparable1} and {@code comparable2}. 240 * @see ObjectUtils#min(Comparable...) 241 * @since 3.13.0 242 */ 243 public static <A extends Comparable<A>> A min(final A comparable1, final A comparable2) { 244 return ObjectUtils.compare(comparable1, comparable2, true) < 0 ? comparable1 : comparable2; 245 } 246 247 private ComparableUtils() { 248 // empty 249 } 250}