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 }