/*************************************** * * * JBoss: The OpenSource J2EE WebOS * * * * Distributable under LGPL license. * * See terms of license at gnu.org. * * * ***************************************/ package org.jboss.util; import java.io.Serializable; /** * A hash-code generator and a collection of static hash-code generation * methods. * * @version $Revision: 1.1 $ * @author Jason Dillon */ public final class HashCode implements Serializable, Cloneable, Comparable { /** Hashcode for a 'null' value. */ private static final int NULL_HASHCODE = 0; /** Hashcode for a 'true' boolean */ private static final int TRUE_HASHCODE = 1231; // completely arbitrary /** Hashcode for a 'false' boolean */ private static final int FALSE_HASHCODE = 1237; // completely arbitrary /** The hash-code value. */ private int value; /** * Construct a new HashCode using the given int as the * base value. * * @param value int to use as the base value. */ public HashCode(final int value) { this.value = value; } /** * Construct a new HashCode. */ public HashCode() { this(0); } /** * Add the hash-code of the given value. * * @param b Value to get hash-code from. * @return This HashCode. */ public HashCode add(final boolean b) { value ^= generate(b); return this; } /** * Add the hash-code of the given value. * * @param n Value to get hash-code from. * @return This HashCode. */ public HashCode add(final byte n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n Value to get hash-code from. * @return This HashCode. */ public HashCode add(final char n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n Value to get hash-code from. * @return This HashCode. */ public HashCode add(final short n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n Value to get hash-code from. * @return This HashCode. */ public HashCode add(final int n) { value ^= n; return this; } /** * Add the hash-code of the given value. * * @param n Value to get hash-code from. * @return This HashCode. */ public HashCode add(final long n) { value ^= generate(n); return this; } /** * Add the hash-code of the given value. * * @param f Value to get hash-code from. * @return This HashCode. */ public HashCode add(final float f) { value ^= generate(f); return this; } /** * Add the hash-code of the given value. * * @param f Value to get hash-code from. * @return This HashCode. */ public HashCode add(final double f) { value ^= generate(f); return this; } /** * Add the hash-code of the given object. * * @param obj Value to get hash-code from. * @return This HashCode. */ public HashCode add(final Object obj) { value ^= generate(obj); return this; } /** * Get the hash-code. * * @return Hash-code. */ public int hashCode() { return (int)value; } /** * Compares this object with the specified int for order. * * @param other Value to compare with. * @return A negative integer, zero, or a positive integer as * this object is less than, equal to, or greater than * the specified object. */ public int compareTo(final int other) { return (value < other) ? -1 : (value == other) ? 0 : 1; } /** * Compares this object with the specified object for order. * * @param other Value to compare with. * @return A negative integer, zero, or a positive integer as * this object is less than, equal to, or greater than * the specified object. * * @throws ClassCastException Object is not a HashCode. */ public int compareTo(final Object obj) throws ClassCastException { HashCode hashCode = (HashCode)obj; return compareTo(hashCode.value); } /** * Test the equality of this HashCode and another object. * * @param obj Object to test equality with. * @return True if object is equal. */ public boolean equals(final Object obj) { if (obj == this) return true; if (obj != null && obj.getClass() == getClass()) { return value == ((HashCode)obj).value; } return false; } /** * Return a string representation of this HashCode. * * @return A string representation of this HashCode. */ public String toString() { return String.valueOf(value); } /** * Return a cloned copy of this HashCode. * * @return Cloned HashCode. */ public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } ///////////////////////////////////////////////////////////////////////// // Generation Methods // ///////////////////////////////////////////////////////////////////////// /** * Generate a hash code for a boolean value. * * @param value Boolean value to generate hash code from. * @return Hash code. */ public static int generate(final boolean value) { return value ? TRUE_HASHCODE : FALSE_HASHCODE; } /** * Generate a hash code for a long value. * * @param value Long value to generate hash code from. * @return Hash code. */ public static int generate(final long value) { return (int)(value ^ (value >> 32)); } /** * Generate a hash code for a double value. * * @param value Double value to generate hash code from. * @return Hash code. */ public static int generate(final double value) { return generate(Double.doubleToLongBits(value)); } /** * Generate a hash code for a float value. * * @param value Float value to generate hash code from. * @return Hash code. */ public static int generate(final float value) { return Float.floatToIntBits(value); } /** * Generate a hash code for a byte array. * * @param bytes An array of bytes to generate a hash code from. * @return Hash code. */ public static int generate(final byte[] bytes) { int hashcode = 0; for (int i=0; iDoes not handle nested primitive array elements. * * @param array Array to generate hashcode for. * @param deep True to traverse elements which are arrays to * determine the elements hash code. * @return Hash code. */ public static int generate(final Object array[], final boolean deep) { int hashcode = 0; for (int i=0; i