首页 > 编程语言 >JAVA 实现 - 哈希表

JAVA 实现 - 哈希表

时间:2024-07-28 14:40:11浏览次数:17  
标签:hash String 实现 str1 System hashCode 哈希 JAVA out

哈希算法 String.hashCode

public static void main(String[] args) {
    String  str1 = "abc";
    String str2 = "bca";

    int hash = 0;
    for (int i = 0; i < str2.length(); i++) {
        char c = str1.charAt(i);
        System.out.println((int)c);

        hash += c;
    }
    System.out.println(hash);
}

以上hash值是将每个字符的值相加得到一个hashcode,但问题是"abc" 与 "cba" 的hashcode 就会一致。如何解决?
可以给前两位字符都乘以一个权重,如下
a * 100 + b * 10 + c
b * 100 + c * 10 + a

实现如下:

public static void main(String[] args) {
    String str1 = "abc";
    String str2 = "bca";

    System.out.println("str1 => String.hashCode:" + str1.hashCode());
    System.out.println("str2 => String.hashCode:" + str2.hashCode());
    int hash = 0;
    for (int i = 0; i < str1.length(); i++) {
        char c = str1.charAt(i);
        System.out.println((int) c); 
        hash = hash * 10 + c;  //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
    }
    System.out.println(hash);
}

还可以进一步优化, 将 hash * 10 改为 乘以一个质数 如31 ,但是为什么是指数那?

public static void main(String[] args) {
    String str1 = "abc";
    String str2 = "bca";

    System.out.println("str1 => String.hashCode:" + str1.hashCode());
    System.out.println("str2 => String.hashCode:" + str2.hashCode());
    int hash = 0;
    for (int i = 0; i < str1.length(); i++) {
        char c = str1.charAt(i);
        System.out.println((int) c);
        hash = hash * 31 + c;  //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
    }
    System.out.println(hash);
}

输出:

str1 => String.hashCode:96354
str2 => String.hashCode:97344
97
98
99
96354

此时输出的hashcode 就是 String 类的实现,还可以进一步优化: 将乘法运算转换为 左移位运算,因为位运算的效率比乘法高,32为 2 的 5次方,因此可以左移5位

public static void main(String[] args) {
    String str1 = "abc";
    String str2 = "bca";

    System.out.println("str1 => String.hashCode:" + str1.hashCode());
    System.out.println("str2 => String.hashCode:" + str2.hashCode());
    int hash = 0;
    for (int i = 0; i < str1.length(); i++) {
        char c = str1.charAt(i);
        System.out.println((int) c);
        hash = (hash << 5) - hash + c;  //loop1: 0+a, loop2: (0+a)*10+b, lopp3: ((0+a)*10+b) * 10 + c <=> a*100 + b*10 +c
    }
    System.out.println(hash);
}

标签:hash,String,实现,str1,System,hashCode,哈希,JAVA,out
From: https://www.cnblogs.com/czzz/p/18328212

相关文章

  • Java 多线程技术详解
    文章目录Java多线程技术详解目录引言多线程的概念为什么使用多线程?多线程的特征多线程的挑战多线程的实现方式3.1继承`Thread`类示例代码:3.2实现`Runnable`接口示例代码:3.3使用`Executor`框架示例代码:3.4使用`Callable`和`Future`示例代码:线程的生命......
  • Java----CAS算法与AtomicInteger源码解读
    CAS介绍:为了确保对数据操作的原子性,在java.util.concurrent.atomic下定义许多关于各种基本类型数据的提供原子操作的类。这里我们以AtomicInteger为例子。AtomicInteger的本质:自旋锁+CAS算法CAS的全称是:CompareAndSwap(比较再交换);是现代CPU广泛支持的一种对内存中的......
  • Nginx 如何实现请求的缓存过期策略?
    ......
  • 简单聊聊JavaScript 中的原型链、null 和 undefined 的区别
    1.原型链个人观点:原型链和逻辑判断里三段论有些类似,一个大前提、一个小前提、一个结论。比如,动物会吃肉,狗是动物,所以狗会吃肉。这也是继承的思想原型和构造函数JavaScript是基于原型的面向对象编程语言,每个对象都有一个内部链接到另一个对象(即原型)。这个机制被称为原型链。原......
  • 如何利用PyQt实现列表添加删除排序功能?
    本文介绍如何实现列表增加删除和排序的功能,效果如下:1页面设计1.1列表#列表数据 self.list=['福宝','萌兰','金虎','蓝天']#创建四行一列标准数据模型self.mode=QStandardItemModel(4,1)#将数据中的列表项作为标准数据模型输出......
  • 如何使用Redis实现一个缓存策略
    使用Redis实现一个缓存策略,主要涉及到数据的存储、读取、更新以及失效处理等方面。下面我将详细介绍如何使用Redis来设计和实现一个基本的缓存策略。1.确定缓存的数据结构和键命名规则首先,你需要决定使用Redis中的哪种数据结构来存储缓存数据,比如字符串(String)、哈希(Hash)、列......
  • 这一文,关于 Java 泛型的点点滴滴 二 (extends、super、<?> 通配符、泛型与反射)
    本文是《这一文,关于Java泛型的点点滴滴》的第二篇,也是最后一篇。在上一篇文章中我们介绍了关于Java泛型的基础知识,而在本文中,我们将深入Java泛型,介绍了extends、super、<?>通配符,并在最后介绍了使用反射获取泛型信息。在阅读本文之前,请先阅读上一篇文章:这一文,关于Jav......
  • [java]小程序,用接口的方式计算两个数的加减乘除
           ......
  • Modelsim仿真实现Verilog HDL频率检测器
     检测输入信号的频率,输出8位数码显示,十进制。可以用于八段式数码管显示屏。1clk产生1Hz的方波,这是个很低的频率,被检测的频率都比这个高,因此,1个周期(即1s)内,可以有很多很多个signal的上升沿,只需要统计signal上升沿的数量,就可以算出signal的频率。在clk第1个上升沿发生后,令......
  • Java 中的集合
    Author:ACatSmilingSince:2024-07-28概述在Java语言中,数组(Array)和集合都是对多个数据进行存储操作的结构,简称Java容器。此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储。数组在内存存储方面的特点:数组一旦初始化以后,其长度就确定了。数组一旦定义好,其元素......