All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.util.HashCode Maven / Gradle / Ivy

The newest version!
/*
*
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netflix.util;


/**
 * Helper class for computing hash codes.
 * 

* The idea here is that objects that define "equals" to * mean that a number of member variables are equal needs a * hash code that is computed from those same member variables. *

* Example: *

 * class MyClass {
 *    ...
 *    private int membVar1;
 *    private OtherClass membVar2;
 *    private float membVar3;
 *    ...
 *    // MyClass objects are equal iff they have the same content.
 *    public boolean equals(Object obj) {
 *        if (obj == this) {
 *            return true;
 *        } else if (obj == null || obj.getClass() != getClass()) {
 *            return false;
 *        }
 *        MyClass cObj = (MyClass)obj;
 *        return (membVar1 == cObj.membVar1)
 *            && HashCode.equalObjects(membVar2, cObj.membVar2)
 *            && (membVar3 == bVar3);
 *    }
 *
 *    // The hash code needs to align with the
 *    // definition of equals.
 *    public int hashCode() {
 *        HashCode h = new HashCode();
 *        h.addValue(membVar1);
 *        h.addValue(membVar2);
 *        h.addValue(membVar2);
 *        return h.hashCode();
 *    }
 *    ...
 * }
 * 
*/ public class HashCode { /* * Based on the algorithm in "Effective Java" */ // ======================================== // Static vars: public, protected, then private // ======================================== private static final int SEED = 17; private static final long SCALE = 37; // ======================================== // Instance vars: public, protected, then private // ======================================== private int mVal; // ======================================== // Constructors // ======================================== /** * Create a new HashCode object */ public HashCode() { mVal = SEED; } // ======================================== // Methods, grouped by functionality, *not* scope // ======================================== /** * Augment the current computed hash code with the * value obj. * * @param obj value being added * @return the new hash code. */ public int addValue(Object obj) { return foldIn((obj != null) ? obj.hashCode() : 0); } /** * Augment the current computed hash code with the * value b. * * @param b value being added * @return the new hash code. */ public int addValue(boolean b) { return foldIn(b ? 0 : 1); } /** * Augment the current computed hash code with the * value i. * * @param i value being added * @return the new hash code. */ public int addValue(byte i) { return foldIn(i); } /** * Augment the current computed hash code with the * value i. * * @param i value being added * @return the new hash code. */ public int addValue(char i) { return foldIn(i); } /** * Augment the current computed hash code with the * value i. * * @param i value being added * @return the new hash code. */ public int addValue(short i) { return foldIn(i); } /** * Augment the current computed hash code with the * value i. * * @param i value being added * @return the new hash code. */ public int addValue(int i) { return foldIn(i); } /** * Augment the current computed hash code with the * value f. * * @param f value being added * @return the new hash code. */ public int addValue(float f) { return foldIn(Float.floatToIntBits(f)); } /** * Augment the current computed hash code with the * value f. * * @param f value being added * @return the new hash code. */ public int addValue(double f) { return foldIn(Double.doubleToLongBits(f)); } // -------------------- // Arrays /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(Object[] array) { int val = hashCode(); for (Object obj : array) { val = addValue(obj); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(boolean[] array) { int val = hashCode(); for (boolean b : array) { val = addValue(b); } return val; } /** * Augment the current computed hash code with the * value i. * * @param array value being added * @return the new hash code. */ public int addValue(byte[] array) { int val = hashCode(); for (byte i : array) { val = addValue(i); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(char[] array) { int val = hashCode(); for (char i : array) { val = addValue(i); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(short[] array) { int val = hashCode(); for (short i : array) { val = addValue(i); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(int[] array) { int val = hashCode(); for (int i : array) { val = addValue(i); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(float[] array) { int val = hashCode(); for (float f : array) { val = addValue(f); } return val; } /** * Augment the current computed hash code with the * value array. * * @param array value being added * @return the new hash code. */ public int addValue(double[] array) { int val = hashCode(); for (double f : array) { val = addValue(f); } return val; } // -------------------- // Utility methods /** * Utility function to make it easy to compare two, possibly null, objects. * * @param o1 first object * @param o2 second object * @return true iff either both objects are null, or * neither are null and they are equal. */ public static boolean equalObjects(Object o1, Object o2) { if (o1 == null) { return (o2 == null); } else if (o2 == null) { return false; } else { return o1.equals(o2); } } // -------------------- // Internals private int foldIn(int c) { return setVal((SCALE * mVal) + c); } private int foldIn(long c) { return setVal((SCALE * mVal) + c); } private int setVal(long l) { mVal = (int)(l ^ (l>>>32)); return mVal; } // ---------------------------------------- // Generic object protocol /** * Get the currently computed hash code value. */ @Override public int hashCode() { return mVal; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj == null || obj.getClass() != getClass()) { return false; } HashCode h = (HashCode)obj; return (h.hashCode() == hashCode()); } @Override public String toString() { return "{HashCode " + mVal + "}"; } } // HashCode




© 2015 - 2024 Weber Informatics LLC | Privacy Policy