001    /*
002     * Copyright (C) 2010 Google Inc.
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    
015    package com.google.common.base;
016    
017    import com.google.common.annotations.Beta;
018    
019    /**
020     * Contains static factory methods for creating {@code Equivalence} instances.
021     *
022     * <p>All methods returns serializable instances.
023     *
024     * @author Bob Lee
025     * @since 4
026     */
027    @Beta
028    public final class Equivalences {
029      private Equivalences() {}
030    
031      /**
032       * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
033       * Does not support null values.
034       */
035      public static Equivalence<Object> equals() {
036        return Impl.EQUALS;
037      }
038    
039      /**
040       * Returns an equivalence that delegates to {@link Object#equals} and {@link Object#hashCode}.
041       * {@link Equivalence#equivalent} returns {@code true} if both values are null, or if neither
042       * value is null and {@link Object#equals} returns {@code true}. {@link Equivalence#hash} throws a
043       * {@link NullPointerException} if passed a null value.
044       */
045      public static Equivalence<Object> nullAwareEquals() {
046        return Impl.NULL_AWARE_EQUALS;
047      }
048    
049      /**
050       * Returns an equivalence that uses {@code ==} to compare values and {@link
051       * System#identityHashCode(Object)} to compute the hash code.  {@link Equivalence#equivalent}
052       * returns {@code true} if both values are null, or if neither value is null and {@code ==}
053       * returns {@code true}. {@link Equivalence#hash} throws a {@link NullPointerException} if passed
054       * a null value.
055       */
056      public static Equivalence<Object> identity() {
057        return Impl.IDENTITY;
058      }
059    
060      private enum Impl implements Equivalence<Object> {
061        EQUALS {
062          public boolean equivalent(Object a, Object b) {
063            return a.equals(b);
064          }
065    
066          public int hash(Object o) {
067            return o.hashCode();
068          }
069        },
070        IDENTITY {
071          public boolean equivalent(Object a, Object b) {
072            return a == b;
073          }
074    
075          public int hash(Object o) {
076            return System.identityHashCode(o);
077          }
078        },
079        NULL_AWARE_EQUALS {
080          public boolean equivalent(Object a, Object b) {
081            return Objects.equal(a, b);
082          }
083    
084          public int hash(Object o) {
085            return o.hashCode(); // TODO: why NPE? counter-intuitive.
086          }
087        },
088      }
089    }