001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.internal;
018
019/**
020 * Utility class for generating integer hash codes.
021 *
022 * <p>
023 * General usage:
024 * <p class='bjava'>
025 *    <jk>int</jk> <jv>hashCode</jv> = HashCode.<jsm>create</jsm>().add(<js>"foobar"</js>).add(<jv>myobject</jv>).add(123).get();
026 * </p>
027 *
028 * <h5 class='section'>See Also:</h5><ul>
029 * </ul>
030 */
031public class HashCode {
032
033   private int hashCode = 1;
034
035   /**
036    * Create a new HashCode object.
037    *
038    * @return A new HashCode object.
039    */
040   public static final HashCode create() {
041      return new HashCode();
042   }
043
044   /**
045    * Calculates a hash code over the specified objects.
046    *
047    * @param objects The objects to calculate a hashcode over.
048    * @return A numerical hashcode value.
049    */
050   public static final int of(Object...objects) {
051      HashCode x = create();
052      for (Object oo : objects)
053         x.add(oo);
054      return x.get();
055   }
056
057   /**
058    * Hashes the hashcode of the specified object into this object.
059    *
060    * @param o The object whose hashcode will be hashed with this object.
061    * @return This object.
062    */
063   public HashCode add(Object o) {
064      o = unswap(o);
065      add(o == null ? 0 : o.hashCode());
066      return this;
067   }
068
069   /**
070    * Hashes the hashcode into this object.
071    *
072    * <p>
073    * The formula is simply <c>hashCode = 31*hashCode + i;</c>
074    *
075    * @param i The hashcode to hash into this object's hashcode.
076    * @return This object.
077    */
078   public HashCode add(int i) {
079      hashCode = 31*hashCode + i;
080      return this;
081   }
082
083   /**
084    * Return the calculated hashcode value.
085    *
086    * @return The calculated hashcode.
087    */
088   public int get() {
089      return hashCode;
090   }
091
092   /**
093    * Converts the object to a normalized form before grabbing it's hashcode.
094    *
095    * <p>
096    * Subclasses can override this method to provide specialized handling (e.g. converting numbers to strings so that
097    * <c>123</c> and <js>"123"</js> end up creating the same hashcode.)
098    *
099    * <p>
100    * Default implementation does nothing.
101    *
102    * @param o The object to normalize before getting it's hashcode.
103    * @return The normalized object.
104    */
105   protected Object unswap(Object o) {
106      return o;
107   }
108}