001/* 002 * Copyright (C) 2010 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 */ 014 015package com.google.common.base; 016 017import static com.google.common.base.Preconditions.checkNotNull; 018 019import com.google.common.annotations.GwtCompatible; 020import com.google.common.annotations.GwtIncompatible; 021import com.google.common.annotations.J2ktIncompatible; 022import com.google.errorprone.annotations.ForOverride; 023import com.google.errorprone.annotations.InlineMe; 024import java.io.Serializable; 025import java.util.function.BiPredicate; 026import org.jspecify.annotations.NonNull; 027import org.jspecify.annotations.Nullable; 028 029/** 030 * A strategy for determining whether two instances are considered equivalent, and for computing 031 * hash codes in a manner consistent with that equivalence. Two examples of equivalences are the 032 * {@linkplain #identity() identity equivalence} and the {@linkplain #equals "equals" equivalence}. 033 * 034 * @author Bob Lee 035 * @author Ben Yu 036 * @author Gregory Kick 037 * @since 10.0 (<a href="https://github.com/google/guava/wiki/Compatibility">mostly 038 * source-compatible</a> since 4.0) 039 */ 040@GwtCompatible 041/* 042 * The type parameter is <T> rather than <T extends @Nullable> so that we can use T in the 043 * doEquivalent and doHash methods to indicate that the parameter cannot be null. 044 */ 045public abstract class Equivalence<T> implements BiPredicate<@Nullable T, @Nullable T> { 046 /** Constructor for use by subclasses. */ 047 protected Equivalence() {} 048 049 /** 050 * Returns {@code true} if the given objects are considered equivalent. 051 * 052 * <p>This method describes an <i>equivalence relation</i> on object references, meaning that for 053 * all references {@code x}, {@code y}, and {@code z} (any of which may be null): 054 * 055 * <ul> 056 * <li>{@code equivalent(x, x)} is true (<i>reflexive</i> property) 057 * <li>{@code equivalent(x, y)} and {@code equivalent(y, x)} each return the same result 058 * (<i>symmetric</i> property) 059 * <li>If {@code equivalent(x, y)} and {@code equivalent(y, z)} are both true, then {@code 060 * equivalent(x, z)} is also true (<i>transitive</i> property) 061 * </ul> 062 * 063 * <p>Note that all calls to {@code equivalent(x, y)} are expected to return the same result as 064 * long as neither {@code x} nor {@code y} is modified. 065 */ 066 public final boolean equivalent(@Nullable T a, @Nullable T b) { 067 if (a == b) { 068 return true; 069 } 070 if (a == null || b == null) { 071 return false; 072 } 073 return doEquivalent(a, b); 074 } 075 076 /** 077 * @deprecated Provided only to satisfy the {@link BiPredicate} interface; use {@link #equivalent} 078 * instead. 079 * @since 21.0 080 */ 081 @InlineMe(replacement = "this.equivalent(t, u)") 082 @Deprecated 083 @Override 084 public final boolean test(@Nullable T t, @Nullable T u) { 085 return equivalent(t, u); 086 } 087 088 /** 089 * Implemented by the user to determine whether {@code a} and {@code b} are considered equivalent, 090 * subject to the requirements specified in {@link #equivalent}. 091 * 092 * <p>This method should not be called except by {@link #equivalent}. When {@link #equivalent} 093 * calls this method, {@code a} and {@code b} are guaranteed to be distinct, non-null instances. 094 * 095 * @since 10.0 (previously, subclasses would override equivalent()) 096 */ 097 @ForOverride 098 protected abstract boolean doEquivalent(T a, T b); 099 100 /** 101 * Returns a hash code for {@code t}. 102 * 103 * <p>The {@code hash} has the following properties: 104 * 105 * <ul> 106 * <li>It is <i>consistent</i>: for any reference {@code x}, multiple invocations of {@code 107 * hash(x}} consistently return the same value provided {@code x} remains unchanged 108 * according to the definition of the equivalence. The hash need not remain consistent from 109 * one execution of an application to another execution of the same application. 110 * <li>It is <i>distributable across equivalence</i>: for any references {@code x} and {@code 111 * y}, if {@code equivalent(x, y)}, then {@code hash(x) == hash(y)}. It is <i>not</i> 112 * necessary that the hash be distributable across <i>inequivalence</i>. If {@code 113 * equivalence(x, y)} is false, {@code hash(x) == hash(y)} may still be true. 114 * <li>{@code hash(null)} is {@code 0}. 115 * </ul> 116 */ 117 public final int hash(@Nullable T t) { 118 if (t == null) { 119 return 0; 120 } 121 return doHash(t); 122 } 123 124 /** 125 * Implemented by the user to return a hash code for {@code t}, subject to the requirements 126 * specified in {@link #hash}. 127 * 128 * <p>This method should not be called except by {@link #hash}. When {@link #hash} calls this 129 * method, {@code t} is guaranteed to be non-null. 130 * 131 * @since 10.0 (previously, subclasses would override hash()) 132 */ 133 @ForOverride 134 protected abstract int doHash(T t); 135 136 /** 137 * Returns a new equivalence relation for {@code F} which evaluates equivalence by first applying 138 * {@code function} to the argument, then evaluating using {@code this}. That is, for any pair of 139 * non-null objects {@code x} and {@code y}, {@code equivalence.onResultOf(function).equivalent(a, 140 * b)} is true if and only if {@code equivalence.equivalent(function.apply(a), function.apply(b))} 141 * is true. 142 * 143 * <p>For example: 144 * 145 * <pre>{@code 146 * Equivalence<Person> SAME_AGE = Equivalence.equals().onResultOf(GET_PERSON_AGE); 147 * }</pre> 148 * 149 * <p>{@code function} will never be invoked with a null value. 150 * 151 * <p>Note that {@code function} must be consistent according to {@code this} equivalence 152 * relation. That is, invoking {@link Function#apply} multiple times for a given value must return 153 * equivalent results. For example, {@code 154 * Equivalence.identity().onResultOf(Functions.toStringFunction())} is broken because it's not 155 * guaranteed that {@link Object#toString}) always returns the same string instance. 156 * 157 * @since 10.0 158 */ 159 public final <F> Equivalence<F> onResultOf(Function<? super F, ? extends @Nullable T> function) { 160 return new FunctionalEquivalence<>(function, this); 161 } 162 163 /** 164 * Returns a wrapper of {@code reference} that implements {@link Wrapper#equals(Object) 165 * Object.equals()} such that {@code wrap(a).equals(wrap(b))} if and only if {@code equivalent(a, 166 * b)}. 167 * 168 * <p>The returned object is serializable if both this {@code Equivalence} and {@code reference} 169 * are serializable (including when {@code reference} is null). 170 * 171 * @since 10.0 172 */ 173 public final <S extends @Nullable T> Wrapper<S> wrap(@ParametricNullness S reference) { 174 return new Wrapper<>(this, reference); 175 } 176 177 /** 178 * Wraps an object so that {@link #equals(Object)} and {@link #hashCode()} delegate to an {@link 179 * Equivalence}. 180 * 181 * <p>For example, given an {@link Equivalence} for {@link String strings} named {@code equiv} 182 * that tests equivalence using their lengths: 183 * 184 * <pre>{@code 185 * equiv.wrap("a").equals(equiv.wrap("b")) // true 186 * equiv.wrap("a").equals(equiv.wrap("hello")) // false 187 * }</pre> 188 * 189 * <p>Note in particular that an equivalence wrapper is never equal to the object it wraps. 190 * 191 * <pre>{@code 192 * equiv.wrap(obj).equals(obj) // always false 193 * }</pre> 194 * 195 * @since 10.0 196 */ 197 public static final class Wrapper<T extends @Nullable Object> implements Serializable { 198 /* 199 * Equivalence's type argument is always non-nullable: Equivalence<Number>, never 200 * Equivalence<@Nullable Number>. That can still produce wrappers of various types -- 201 * Wrapper<Number>, Wrapper<Integer>, Wrapper<@Nullable Integer>, etc. If we used just 202 * Equivalence<? super T> below, no type could satisfy both that bound and T's own 203 * bound. With this type, they have some overlap: in our example, Equivalence<Number> 204 * and Equivalence<Object>. 205 */ 206 private final Equivalence<? super @NonNull T> equivalence; 207 208 @ParametricNullness private final T reference; 209 210 private Wrapper(Equivalence<? super @NonNull T> equivalence, @ParametricNullness T reference) { 211 this.equivalence = checkNotNull(equivalence); 212 this.reference = reference; 213 } 214 215 /** Returns the (possibly null) reference wrapped by this instance. */ 216 @ParametricNullness 217 public T get() { 218 return reference; 219 } 220 221 /** 222 * Returns {@code true} if {@link Equivalence#equivalent(Object, Object)} applied to the wrapped 223 * references is {@code true} and both wrappers use the {@link Object#equals(Object) same} 224 * equivalence. 225 */ 226 @Override 227 public boolean equals(@Nullable Object obj) { 228 if (obj == this) { 229 return true; 230 } 231 if (obj instanceof Wrapper) { 232 Wrapper<?> that = (Wrapper<?>) obj; // note: not necessarily a Wrapper<T> 233 234 if (this.equivalence.equals(that.equivalence)) { 235 /* 236 * We'll accept that as sufficient "proof" that either equivalence should be able to 237 * handle either reference, so it's safe to circumvent compile-time type checking. 238 */ 239 @SuppressWarnings("unchecked") 240 Equivalence<Object> equivalence = (Equivalence<Object>) this.equivalence; 241 return equivalence.equivalent(this.reference, that.reference); 242 } 243 } 244 return false; 245 } 246 247 /** Returns the result of {@link Equivalence#hash(Object)} applied to the wrapped reference. */ 248 @Override 249 public int hashCode() { 250 return equivalence.hash(reference); 251 } 252 253 /** 254 * Returns a string representation for this equivalence wrapper. The form of this string 255 * representation is not specified. 256 */ 257 @Override 258 public String toString() { 259 return equivalence + ".wrap(" + reference + ")"; 260 } 261 262 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 0; 263 } 264 265 /** 266 * Returns an equivalence over iterables based on the equivalence of their elements. More 267 * specifically, two iterables are considered equivalent if they both contain the same number of 268 * elements, and each pair of corresponding elements is equivalent according to {@code this}. Null 269 * iterables are equivalent to one another. 270 * 271 * <p>Note that this method performs a similar function for equivalences as {@link 272 * com.google.common.collect.Ordering#lexicographical} does for orderings. 273 * 274 * <p>The returned object is serializable if this object is serializable. 275 * 276 * @since 10.0 277 */ 278 @GwtCompatible(serializable = true) 279 public final <S extends @Nullable T> Equivalence<Iterable<S>> pairwise() { 280 // Ideally, the returned equivalence would support Iterable<? extends T>. However, 281 // the need for this is so rare that it's not worth making callers deal with the ugly wildcard. 282 return new PairwiseEquivalence<>(this); 283 } 284 285 /** 286 * Returns a predicate that evaluates to true if and only if the input is equivalent to {@code 287 * target} according to this equivalence relation. 288 * 289 * @since 10.0 290 */ 291 public final Predicate<@Nullable T> equivalentTo(@Nullable T target) { 292 return new EquivalentToPredicate<>(this, target); 293 } 294 295 private static final class EquivalentToPredicate<T> 296 implements Predicate<@Nullable T>, Serializable { 297 298 private final Equivalence<T> equivalence; 299 private final @Nullable T target; 300 301 EquivalentToPredicate(Equivalence<T> equivalence, @Nullable T target) { 302 this.equivalence = checkNotNull(equivalence); 303 this.target = target; 304 } 305 306 @Override 307 public boolean apply(@Nullable T input) { 308 return equivalence.equivalent(input, target); 309 } 310 311 @Override 312 public boolean equals(@Nullable Object obj) { 313 if (this == obj) { 314 return true; 315 } 316 if (obj instanceof EquivalentToPredicate) { 317 EquivalentToPredicate<?> that = (EquivalentToPredicate<?>) obj; 318 return equivalence.equals(that.equivalence) && Objects.equal(target, that.target); 319 } 320 return false; 321 } 322 323 @Override 324 public int hashCode() { 325 return Objects.hashCode(equivalence, target); 326 } 327 328 @Override 329 public String toString() { 330 return equivalence + ".equivalentTo(" + target + ")"; 331 } 332 333 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 0; 334 } 335 336 /** 337 * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}. 338 * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither 339 * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} returns 340 * {@code 0} if passed a null value. 341 * 342 * @since 13.0 343 * @since 8.0 (in Equivalences with null-friendly behavior) 344 * @since 4.0 (in Equivalences) 345 */ 346 public static Equivalence<Object> equals() { 347 return Equals.INSTANCE; 348 } 349 350 /** 351 * Returns an equivalence that uses {@code ==} to compare values and {@link 352 * System#identityHashCode(Object)} to compute the hash code. {@link Equivalence#equivalent} 353 * returns {@code true} if {@code a == b}, including in the case that a and b are both null. 354 * 355 * @since 13.0 356 * @since 4.0 (in Equivalences) 357 */ 358 public static Equivalence<Object> identity() { 359 return Identity.INSTANCE; 360 } 361 362 static final class Equals extends Equivalence<Object> implements Serializable { 363 364 static final Equals INSTANCE = new Equals(); 365 366 @Override 367 protected boolean doEquivalent(Object a, Object b) { 368 return a.equals(b); 369 } 370 371 @Override 372 protected int doHash(Object o) { 373 return o.hashCode(); 374 } 375 376 private Object readResolve() { 377 return INSTANCE; 378 } 379 380 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 1; 381 } 382 383 static final class Identity extends Equivalence<Object> implements Serializable { 384 385 static final Identity INSTANCE = new Identity(); 386 387 @Override 388 protected boolean doEquivalent(Object a, Object b) { 389 return false; 390 } 391 392 @Override 393 protected int doHash(Object o) { 394 return System.identityHashCode(o); 395 } 396 397 private Object readResolve() { 398 return INSTANCE; 399 } 400 401 @GwtIncompatible @J2ktIncompatible private static final long serialVersionUID = 1; 402 } 403}