package edu.harvard.i2b2.pm.services;
/*
* Copyright 2006-2007 The Herringroe Team.
*
* 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.
*/
import java.util.Arrays;
import java.util.Iterator;
/**
* <code><pre>
* public int hashCode(){
* return new HashCodeBuilder().
* append(field1).
* append(field2).
* append(field3).
* getHashCode();
* }
* </pre></code>
*
* @see Object#hashCode()
*
* @author Katsunori Koyanagi
* @version 1.0
*/
public class HashCodeBuilder {
private static class PrimeNumberIterator implements Iterator<Integer> {
private int idx = 0;
PrimeNumberIterator() {
}
/**
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return true;
}
/**
* @see java.util.Iterator#next()
*/
public Integer next() {
this.idx++;
if (this.idx == HashCodeBuilder.PRIME_NUMBERS.length) {
this.idx = 0;
}
return HashCodeBuilder.PRIME_NUMBERS[this.idx];
}
/**
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException();
}
}
private static final int[] PRIME_NUMBERS = new int[] { 13, 31, 73, 127,
179, 233, 283, 353, 419, 467, 547, 607, 661, 739, 811, 877, 947,
1019, 1087, 1153, 1229, 1297, 1381, 1453, 1523, 1597, 1663, 1741,
1823, 1901, 1993, 2063, 2131, 2221, 2293, 2371, 2437, 2539, 2621,
2689, 2749, 2833, 2909, 3001, 3083, 3187, 3259, 3343, 3433, 3517,
3581, 3659, 3733, 3823, 3911, 4001, 4073, 4153, 4241, 4327, 4421,
4507, 4591, 4663, 4759, 4861, 4943, 5009, 5099, 5189, 5281, 5393,
5449, 5527, 5641, 5701, 5801, 5861, 5953, 6067, 6143, 6229, 6311,
6373, 6481, 6577, 6679, 6763, 6841, 6947, 7001, 7109, 7211, 7307,
7417, 7507, 7573, 7649, 7727, 7841, 7927, 8039, 8117, 8221, 8293,
8389, 8513, 8599, 8681, 8747, 8837, 8933, 9013, 9127, 9203, 9293,
9391, 9461, 9539, 9643, 9739, 9817, 9901, 10009, 10103, 10181,
10273, 10357 };
private int hashCode;
private PrimeNumberIterator primeNumbers;
public HashCodeBuilder() {
this.primeNumbers = new PrimeNumberIterator();
this.hashCode = 0;
}
public HashCodeBuilder append(Object value) {
this.hashCode = this.hashCode
+ this.computeHashCode(this.primeNumbers.next(), value);
return this;
}
private int computeHashCode(int prime, Object value) {
if (value == null) {
return 0;
}
int hash;
if (value.getClass().isArray()) {
Class<?> type = value.getClass().getComponentType();
if (type == int.class) {
hash = Arrays.hashCode((int[]) value);
} else if (type == double.class) {
hash = Arrays.hashCode((int[]) value);
} else if (type == char.class) {
hash = Arrays.hashCode((char[]) value);
} else if (type == boolean.class) {
hash = Arrays.hashCode((boolean[]) value);
} else if (type == long.class) {
hash = Arrays.hashCode((long[]) value);
} else if (type == float.class) {
hash = Arrays.hashCode((float[]) value);
} else if (type == short.class) {
hash = Arrays.hashCode((short[]) value);
} else if (type == byte.class) {
hash = Arrays.hashCode((byte[]) value);
} else {
PrimeNumberIterator iterator = new PrimeNumberIterator();
Object[] values = (Object[]) value;
hash = 0;
for (Object element : values) {
hash = hash
+ this.computeHashCode(prime * iterator.next(),
element);
}
}
} else {
hash = value.hashCode();
}
return hash * prime;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
public int getHashCode() {
return this.hashCode;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return this.hashCode;
}
}