Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6431610
Votes 0
Synopsis (coll) util.Hashing class
Category java:classes_util
Reported Against
Release Fixed
State 5-Cause Known, request for enhancement
Priority: 4-Low
Related Bugs
Submit Date 30-MAY-2006
Description
A DESCRIPTION OF THE REQUEST :
It would be convenient if there were a class in the library that helps with writing a hashCode() method.

JUSTIFICATION :
It's not obvious how to do  customer  hashing.  Better algorithms can be invented in the future.  Everyone is writing their own copy of the same code (more or less).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Methods in the library to help one write a  customer  hashCode() method.
ACTUAL -
You're on your own.

CUSTOMER SUBMITTED WORKAROUND :
package util;

/**
 * Calculate a hash code.
 *
 * Algorithm is from Josh Bloch's book <quote>Effective Java</quote>.
 */
public class Hashing {

  private static final int MAGIC_PRIME1 = 17;
  private static final int MAGIC_PRIME2 = 37;

  /**
   * Make a hash code from a sequence of ints.
   *
   * @param field ints to be made into a hash code
   * @return the hash code
   */
  public static int makeHashCodeInt(int... field) {
    int result = initial();
    for (int i = 0; i < field.length; ++i) {
      int hashCode = field[i];
      result = next(result, hashCode);
    }
    return result;
  }

  /**
   * Make a hash code from sequence of objects.
   *
   * Note: should probably hard code Double because the standard implementation
   * uses Double.doubleToLongBits() instead of Double.doubleToRawLongBits()
   * and does only a simple xor.
   *
   * @param field objects and numbers to be made into a hash code
   * @return the hash code
   */
  public static int makeHashCode(Object... field) {
    int result = initial();
    for (int i = 0; i < field.length; ++i) {
      Object obj = field[i];
      int hashCode = obj == null ? 0 : obj.hashCode();
      result = next(result, hashCode);
    }
    return result;
  }

  /**
   * Provide the initial value for the hash code.
   *
   * @return hash code initial value
   */
  public static int initial() {
    return MAGIC_PRIME1;
  }

  /**
   * Combine a new value's hash code into the accumulated hash code.
   *
   * @param accumulatedHashCode the hash code so far
   * @param newHashCode the hash code to be combined
   * @return
   */
  public static int next(int accumulatedHashCode, int newHashCode) {
    return MAGIC_PRIME2 * accumulatedHashCode + newHashCode;
  }

  //============================================================================

  public static void main(String[] args) {
    Test test = new Test();
    System.out.println(test.hashCode());
  }
}

//==============================================================================

class Test {
  int foo = 2;
  Integer bar = 3;
  Test2 test2 = new Test2();
  Test3 test3 = new Test3();
  Test4 test4 = new Test4();
  Object baz;

  public int hashCode() {
    return Hashing.makeHashCode(foo, bar, test2, test3, test4, baz);
  }
}

//==============================================================================

class Test2 {
  int foo = 1;
  int bar = 2;

  public int hashCode() {
    // All fields are ints; no boxing required.
    return Hashing.makeHashCodeInt(foo, bar);
  }
}

//==============================================================================

class Test3 {
  int foo = 1;
  double bar = 2;

  public int hashCode() {
    // The double requires boxing.
    return Hashing.makeHashCode(foo, bar);
  }
}

//==============================================================================

class Test4 {
}
Posted Date : 2006-05-30 10:46:09.0
Work Around
N/A
Evaluation
Worthy of consideration
Posted Date : 2006-05-30 14:02:45.0
Comments
  
  Include a link with my name & email   

Submitted On 20-FEB-2007
daveyost
I entered this report.


Submitted On 22-JUN-2007
remi_forax
There ia another implementation here:
http://www.javapractices.com/Topic28.cjp

Rémi



PLEASE NOTE: JDK6 is formerly known as Project Mustang