1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.apache.harmony.misc; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is a convenience method to sequentially calculate hash code of the 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object based on the field values. The result depends on the order of elements 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * appended. The exact formula is the same as for 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>java.util.List.hashCode</code>. 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If you need order independent hash code just summate, multiply or XOR all 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * elements. 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Suppose we have class: 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre><code> 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class Thing { 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * long id; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * String name; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * float weight; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * } 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </code></pre> 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The hash code calculation can be expressed in 2 forms. 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For maximum performance: 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <pre><code> 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public int hashCode() { 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * int hashCode = HashCode.EMPTY_HASH_CODE; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hashCode = HashCode.combine(hashCode, id); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hashCode = HashCode.combine(hashCode, name); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hashCode = HashCode.combine(hashCode, weight); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return hashCode; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * } 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </code></pre> 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p> 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For convenience: <code><pre> 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public int hashCode() { 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return new HashCode().append(id).append(name).append(weight).hashCode(); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </code></pre> 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.util.List#hashCode() 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class HashCode { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The hashCode value before any data is appended, equals to 1. 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.util.List#hashCode() 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static final int EMPTY_HASH_CODE = 1; 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int hashCode = EMPTY_HASH_CODE; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns accumulated hashCode 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final int hashCode() { 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return hashCode; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, boolean value) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int v = value ? 1231 : 1237; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return combine(hashCode, v); 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, long value) { 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int v = (int) (value ^ (value >>> 32)); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return combine(hashCode, v); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, float value) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int v = Float.floatToIntBits(value); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return combine(hashCode, v); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, double value) { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long v = Double.doubleToLongBits(value); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return combine(hashCode, v); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, Object value) { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return combine(hashCode, value.hashCode()); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines hashCode of previous elements sequence and value's hashCode. 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param hashCode previous hashCode value 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return combined hashCode 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static int combine(int hashCode, int value) { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 31 * hashCode + value; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(int value) { 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(long value) { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(float value) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(double value) { 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(boolean value) { 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Appends value's hashCode to the current hashCode. 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param value new element 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final HashCode append(Object value) { 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hashCode = combine(hashCode, value); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return this; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 204