java8 hash算法
Posted 茅坤宝骏氹
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8 hash算法相关的知识,希望对你有一定的参考价值。
一、hash算法
哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。
二、jdk的hash算法实现
(1)Interger
private final int value; @Override public int hashCode() { return Integer.hashCode(value); } public static int hashCode(int value) { return value; }
Integer的hash算法就是直接获取它的数值。int整数范围很大,分散广冲突小。
(2)Short
private final short value; @Override public int hashCode() { return Short.hashCode(value); } public static int hashCode(short value) { return (int)value; }
(3)Byte
private final byte value; @Override public int hashCode() { return Byte.hashCode(value); } public static int hashCode(byte value) { return (int)value; }
(4)Long
private final long value; @Override public int hashCode() { return Long.hashCode(value); } public static int hashCode(long value) { return (int)(value ^ (value >>> 32)); }
long类型作为索引范围太大,需要转为int类型。这里简单的获取低32位容易导致散列不均,因为高位部分没有被利用。所以这里采用逻辑右移32位,让高32位和低32位进行XOR操作,导致高位低位都能被利用到
(5)Double
private final double value; @Override public int hashCode() { return Double.hashCode(value); } public static int hashCode(double value) { long bits = doubleToLongBits(value); return (int)(bits ^ (bits >>> 32)); }
由于double不能当成索引,所以需要转换成整数
由于double数据类型底层采用64位bit码表示,采用IEEE浮点标准编码。如果将它使用8字节整数编码方式,就能获取一个long类型的数字
long类型作为索引范围太大,需要转为int类型。这里简单的获取低32位容易导致散列不均,因为高位部分没有被利用。所以这里采用逻辑右移32位,让高32位和低32位进行XOR操作,导致高位低位都能被利用到
最后得到的数字强转int,只保留已经被充分打乱的低32位
(6)Float
private final float value; @Override public int hashCode() { return Float.hashCode(value); } public static int hashCode(float value) { return floatToIntBits(value); } public static int floatToIntBits(float value) { int result = floatToRawIntBits(value); // Check for NaN based on values of bit fields, maximum // exponent and nonzero significand. if ( ((result & FloatConsts.EXP_BIT_MASK) == FloatConsts.EXP_BIT_MASK) && (result & FloatConsts.SIGNIF_BIT_MASK) != 0) result = 0x7fc00000; return result; } public static native int floatToRawIntBits(float value);
public class FloatConsts { public static final int EXP_BIT_MASK = 2139095040; public static final int SIGNIF_BIT_MASK = 8388607; //... }
(7)Boolean
private final boolean value; @Override public int hashCode() { return Boolean.hashCode(value); } public static int hashCode(boolean value) { return value ? 1231 : 1237; }
(8)Character
private final char value; @Override public int hashCode() { return Character.hashCode(value); } public static int hashCode(char value) { return (int)value; }
(9)String
private final char value[]; public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
(10)Object
public native int hashCode();
(11)自定义对象
public class Node<T> { private T data; private Node<T> next = null; @Override public int hashCode() { int hash = 3; hash = 97 * hash + Objects.hashCode(this.data); hash = 97 * hash + Objects.hashCode(this.next); return hash; } }
public final class Objects { public static int hashCode(Object o) { return o != null ? o.hashCode() : 0; } //... }
(12)HashMap
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } public int hashCode() { int h = 0; Iterator<Entry<K,V>> i = entrySet().iterator(); while (i.hasNext()) h += i.next().hashCode(); return h; }
(13)Hashtable
public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; } public synchronized int hashCode() { int h = 0; if (count == 0 || loadFactor < 0) return h; // Returns zero loadFactor = -loadFactor; // Mark hashCode computation in progress Entry<?,?>[] tab = table; for (Entry<?,?> entry : tab) { while (entry != null) { h += entry.hashCode(); entry = entry.next; } } loadFactor = -loadFactor; // Mark hashCode computation complete return h; }
以上是关于java8 hash算法的主要内容,如果未能解决你的问题,请参考以下文章