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