001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.schematic.internal; 017 018import java.util.Arrays; 019 020/** 021 * Utilities for easily computing hash codes. The algorithm should generally produce good distributions for use in hash-based 022 * containers or collections, but as expected does always result in repeatable hash codes given the inputs. 023 */ 024public class HashCode { 025 026 // Prime number used in improving distribution: 1,000,003 027 private static final int PRIME = 103; 028 029 /** 030 * Compute a combined hash code from the supplied objects. This method always returns 0 if no objects are supplied. 031 * 032 * @param objects the objects that should be used to compute the hash code 033 * @return the hash code 034 */ 035 public static int compute( Object... objects ) { 036 return _compute(0, objects); 037 } 038 039 /** 040 * Compute a combined hash code from the supplied objects using the supplied seed. 041 * 042 * @param seed a value upon which the hash code will be based; may be 0 043 * @param objects the objects that should be used to compute the hash code 044 * @return the hash code 045 */ 046 protected static int _compute( int seed, 047 Object... objects ) { 048 if (objects == null || objects.length == 0) { 049 return seed * HashCode.PRIME; 050 } 051 // Compute the hash code for all of the objects ... 052 int hc = seed; 053 for (Object object : objects) { 054 hc = HashCode.PRIME * hc; 055 if (object instanceof byte[]) { 056 hc += Arrays.hashCode((byte[])object); 057 } else if (object instanceof boolean[]) { 058 hc += Arrays.hashCode((boolean[])object); 059 } else if (object instanceof short[]) { 060 hc += Arrays.hashCode((short[])object); 061 } else if (object instanceof int[]) { 062 hc += Arrays.hashCode((int[])object); 063 } else if (object instanceof long[]) { 064 hc += Arrays.hashCode((long[])object); 065 } else if (object instanceof float[]) { 066 hc += Arrays.hashCode((float[])object); 067 } else if (object instanceof double[]) { 068 hc += Arrays.hashCode((double[])object); 069 } else if (object instanceof char[]) { 070 hc += Arrays.hashCode((char[])object); 071 } else if (object instanceof Object[]) { 072 hc += Arrays.hashCode((Object[])object); 073 } else if (object != null) { 074 hc += object.hashCode(); 075 } 076 } 077 return hc; 078 } 079 080}