001 /*
002 * JBoss, Home of Professional Open Source.
003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004 * as indicated by the @author tags. See the copyright.txt file in the
005 * distribution for a full listing of individual contributors.
006 *
007 * This is free software; you can redistribute it and/or modify it
008 * under the terms of the GNU Lesser General Public License as
009 * published by the Free Software Foundation; either version 2.1 of
010 * the License, or (at your option) any later version.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022 package org.jboss.dna.common.util;
023
024 import java.util.Arrays;
025
026 /**
027 * Utilities for easily computing hash codes. The algorithm should generally produce good distributions for use in hash-based
028 * containers or collections, but as expected does always result in repeatable hash codes given the inputs.
029 * @author Randall Hauch
030 */
031 public class HashCode {
032
033 // Prime number used in improving distribution: 1,000,003
034 private static final int PRIME = 103;
035
036 /**
037 * Compute a combined hash code from the supplied objects. This method always returns 0 if no objects are supplied.
038 * @param objects the objects that should be used to compute the hash code
039 * @return the hash code
040 */
041 public static int compute( Object... objects ) {
042 return compute(0, objects);
043 }
044
045 /**
046 * Compute a combined hash code from the supplied objects using the supplied seed.
047 * @param seed a value upon which the hash code will be based; may be 0
048 * @param objects the objects that should be used to compute the hash code
049 * @return the hash code
050 */
051 protected static int compute( int seed, Object... objects ) {
052 if (objects == null || objects.length == 0) {
053 return seed * HashCode.PRIME;
054 }
055 // Compute the hash code for all of the objects ...
056 int hc = seed;
057 for (Object object : objects) {
058 hc = HashCode.PRIME * hc;
059 if (object instanceof byte[]) {
060 hc += Arrays.hashCode((byte[])object);
061 } else if (object instanceof boolean[]) {
062 hc += Arrays.hashCode((boolean[])object);
063 } else if (object instanceof short[]) {
064 hc += Arrays.hashCode((short[])object);
065 } else if (object instanceof int[]) {
066 hc += Arrays.hashCode((int[])object);
067 } else if (object instanceof long[]) {
068 hc += Arrays.hashCode((long[])object);
069 } else if (object instanceof float[]) {
070 hc += Arrays.hashCode((float[])object);
071 } else if (object instanceof double[]) {
072 hc += Arrays.hashCode((double[])object);
073 } else if (object instanceof char[]) {
074 hc += Arrays.hashCode((char[])object);
075 } else if (object instanceof Object[]) {
076 hc += Arrays.hashCode((Object[])object);
077 } else if (object != null) {
078 hc += object.hashCode();
079 }
080 }
081 return hc;
082 }
083
084 }