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