java8 hash算法

一、hash算法

  哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。

 

二、对象hash总结

Integer、Byte、Short、Character都是转换为int类型作为hashcode

Boolean true值hashcode为1231,false值hashcode为1237

Long  取高32位和低32位与值转成int类型作为hashcode

Double  将64bit值转成long类型,然后按照Long类型进行获取hashcode

Float  将32bit值转成int类型,检查int值是否来自NAN值转换的,若是hashcode为0x7fc00000,否则为该转换值。

String 将字符串里面的字符以31进制求和,既hash=hash*31+value[i]

Object 以内存首字节的地址进行计算hash值

HashMap 将所有Entry的hashcode相加组成HashMap的hashcode

Hashtable EntrySet长度0或者加载因子小于0时,hashcode为0,否则将所有key的hashcode相加组成HashMap的hashcode

 

三、jdk的hash算法实现

(1)Interger

    private final int value;
@Overridepublic int hashCode() {return Integer.hashCode(value);}
public static int hashCode(int value) {return value;}

Integer的hash算法就是直接获取它的数值。int整数范围很大,分散广冲突小。

 

(2)Short

    private final short value;@Overridepublic int hashCode() {return Short.hashCode(value);}public static int hashCode(short value) {return (int)value;}

 

(3)Byte

    private final byte value;@Overridepublic int hashCode() {return Byte.hashCode(value);}public static int hashCode(byte value) {return (int)value;}

 

(4)Long

    private final long value;@Overridepublic 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;@Overridepublic 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;@Overridepublic 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;@Overridepublic int hashCode() {return Boolean.hashCode(value);}public static int hashCode(boolean value) {return value ? 1231 : 1237;}

采用两个质数作为true或false的索引。这两个质数足够大,用来作为索引时,出现碰撞的可能性低。

 

(8)Character

    private final char value;@Overridepublic 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;}

 采用质数31作为基数,逐位加权,打乱整个字符的权重和排列位置,使得散列效果更好。

 

(10)Object

    public native int hashCode();

 

(11)自定义对象

public class Node<T> {private T data;private Node<T> next = null;@Overridepublic 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 nullif (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 progressEntry<?,?>[] tab = table;for (Entry<?,?> entry : tab) {while (entry != null) {h += entry.hashCode();entry = entry.next;}}loadFactor = -loadFactor;  // Mark hashCode computation completereturn h;}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

exchanger_如何通过示例在Java中使用Exchanger

exchanger大家好&#xff0c;如果您在并发Java应用程序中工作&#xff0c;那么您可能听说过java.util.concurrent包的Exchanger类。 Java中的Exchanger是Java 1.5中与CountDownLatch &#xff0c; CyclicBarrier和Semaphores一起引入的另一个并发或同步实用程序。 顾名思义&…

Java Enumeration接口与Iterator接口

一、Enumeration接口 Enumeration接口中定义了一些方法&#xff0c;通过这些方法可以枚举&#xff08;一次获得一个&#xff09;对象集合中的元素。 这种传统接口已被迭代器取代&#xff0c;虽然Enumeration 还未被遗弃&#xff0c;但在现在代码中已经被很少使用了。尽管如此&a…

java国际化——日期和时间+排序

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——日期和时间排序 的基础知识 &#xff1b; 【1】日期和时间 1&#xff09;当格式化日期和时间时&#xff0c;需要考虑4个与 Locale …

jvm 垃圾收集算法_JVM垃圾收集和优化

jvm 垃圾收集算法总览 在对系统进行性能相关问题的故障排除时&#xff0c;内存优化是一个需要深入分析每个系统在内存中存储的内容&#xff0c;存储时间和访问方式的场所。 这篇文章是要对背景信息进行注释&#xff0c;并在此工作中要注意一些要点&#xff0c;这些工作要针对基…

数据库SQL索引

一、索引的意义 表中创建索引&#xff0c;以便更加快速高效地查询数据。 用户无法看到索引&#xff0c;它们只能被用来加速搜索/查询。 注释&#xff1a;更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间&#xff0c;这是由于索引本身也需要更新。因此&#x…

java国际化——消息格式化+文本文件和字符集

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java国际化——消息格式化文本文件和字符集 的基础知识 &#xff1b; 2&#xff09; 由于本文涉及到的源代码都比较简单&#xff0c;所以直接将全…

java 8 新功能详解_Java 8和Java 14之间的新功能

java 8 新功能详解从版本9开始&#xff0c;Java每6个月就有一次新功能&#xff0c;因此很难跟踪这些新更改。 互联网上的大多数信息都描述了最近2个Java版本之间的变化。 但是&#xff0c;如果您的情况与我相似&#xff0c;则说明您使用的不是Java的最新版本&#xff0c;而是使…

Tomcat配置虚拟内存

一、Tomcat启动参数JAVA_OPTS参数说明   -server 启用jdk 的 server 版&#xff1b;   -Xms java 虚拟机初始化时的堆最小内存&#xff1b;   -Xmx java 虚拟机可使用堆的最大内存&#xff1b;   -XX: PermSize 非堆内存永久保留区域   -XX:MaxPermS…

ISO语言代码和国家代码+Locale常量+ISO货币符号

【1】ISO语言代码和国家代码 【2】Locale常量 【3】ISO货币符号

djl和ljl_使用Spring Boot和DJL进行深度学习

djl和ljl总览 这是Spring Boot上的另一篇文章 &#xff0c;该文章将展示如何使用Deep Java Library &#xff08;DJL&#xff09;构建示例Web应用程序&#xff0c; Deep Java Library &#xff08;DJL&#xff09;是Java的开源深度学习库&#xff0c;用于诊断X射线图像上的COVI…

java BigDecimal八种舍入模式

一、BigDecimal介绍java.math.BigDecimal不可变的immutable、任意精度的有符号十进制数。BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成。标度(scale)如果为零或正数&#xff0c;则标度是小数点后的位数。如果为负数&#xff0c;则将该数的非标度值乘以10的…

java国际化——资源包

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 旨在理解 java国际化——资源包 的基础知识 &#xff1b; 2&#xff09; 本文源代码idea 转自&#xff1a; &#xff08;利用properties 文件进行国际化&#xff09;https://docs.oracle.co…

ui自动化测试测试报告_您需要了解的有关UI测试的所有信息

ui自动化测试测试报告让我们从一个问题开始。 用户在网站上进行互动的第一件事是什么&#xff1f; 接口&#xff0c;当然。 网站的外观是在用户身上产生“第一印象”的第一件事。 交互式Web应用程序可以为用户带来成败&#xff0c;这就是为什么越来越多的人选择对其Web应用程序…

Tomcat解决HTTP GET中文乱码

一、中文乱码原因 Tomcat默认是按ISO-8859-1进行URL解码&#xff0c;ISO-8859-1并未包括中文字符&#xff0c;中文字符不能被正确解析了。 二、配置编码 在tomcat的conf/server.xml下的connetor属性中增加URIEncoding或者useBodyEncodingForURI属性 &#xff08;1&#xff0…

NanoHTTPD web server的一个简单荔枝

【0】README 0.1&#xff09;本文旨在演示一个简单荔枝&#xff0c;以说明如何使用 NanoHTTPD web server 和 浏览器访问 该server的效果 -------------------------------------------------------------- App.java public class App extends NanoHTTPD {public App() thr…

throwable_您想了解的所有Throwable

throwable本文是有关异常的教程。 但不是通常的一种。 其中有许多内容可以告诉您异常的含义&#xff0c;如何抛出异常&#xff0c;捕获异常&#xff0c;已检查异常和运行时异常之间的区别&#xff0c;等等。 没有必要了。 这对您来说也很无聊。 如果没有&#xff0c;那么请阅读…

Linux Tomcat安装

一、linux 安装软件的步骤 &#xff08;1&#xff09;下载软件的压缩包 &#xff08;2&#xff09;解压到指定的目录 &#xff08;3&#xff09;配置环境变量 &#xff0c;配置PATH&#xff08;在任意目录启动&#xff0c;这PATH可以省略&#xff0c;若不配置只有安装目录才…

java分布式对象(RMI+部署使用RMI的程序)

【0】README 1&#xff09;本文文字转自 core java volume 2&#xff0c; 旨在学习 java 分布式对象的相关知识&#xff1b; 2&#xff09; RMI 的实例程序为原创&#xff1b; 3&#xff09; RMI部署步骤的测试用例&#xff0c;参见 http://blog.csdn.net/pacosonswjtu/arti…

java 创建uri_使用UriBuilder快速创建URI

java 创建uri如果您有权访问JAX-RS API和项目中的实现&#xff08;很多&#xff09;&#xff0c;则可以使用JAX-RS的UriBuilder通过使用可解析占位符的构建器模式方便地创建URI。 看下面的例子&#xff1a; String host System.getProperty( "host" , "localh…

Tomcat 服务自动启动

一、配置/etc/rc.local rc.local是linux启动init之后执行的脚本。 sudo vi /etc/rc.local 添加如下一行 /home/myuser/software/apache-tomcat-7.0.29/bin/startup.sh&#xff08;脚本绝对路径&#xff09; 二、sysv-rc-conf 工具配置 1、安装 sysv-rc-conf sudo apt-get …