Java实现哈希表
2、哈希表
2.1、哈希冲突
冲突位置,把数据构建为链表结构。
装载因子=哈希表中的元素个数 / (散列表)哈希表的长度
装载因子越大,说明链表越长,性能就越低,那么哈希表就需要扩容,把数据迁移到新的哈希表中!
数据会经过两层比较:
一个是对哈希值的比较 使用hashcode()方法
另一个是对key值的比较,使用equals()方法
如果两个对象相同,hashcode一定相同。
但是hashcode相同,两个对象不一定相同。
哈希冲突是指,不同的key经由哈希函数,映射到了相同的位置上,造成的冲突。
/**
* @author Administrator
* @date 2022-09-09 14:28
*/
public class MyHashTable<K,V> {
private Node<K, V>[] table; // 实例化一个Node数组 Node数组本身又是个链表
private static class Node<K,V>{
final int hash; //hash值
final K key;
V value;
Node<K,V> next; //下一个节点 kv对
public Node(int hash, K key, V value, Node<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
}
public MyHashTable(int capacity) {
table = (Node<K,V>[]) new Node[capacity];
}
public void put (K key,V value){
// 1. 计算哈希值
int hash = hash(key);
// 2. 计算数组的索引值
int i = (table.length-1) & hash;
// 3. 把当前的kv对 存到Node里
Node<K,V> node = new Node (hash,key,value,null);
// 4. 根据索引下标 拿到目前table里的数据 然后进行对比
Node<K,V> kvNode = table[i];
if(kvNode == null ){
// 如果为空 则说明当前位置没有数据 可以直接存
table[i] = node;
return;
}
// 如果有值 就去看 key是否一样
if(kvNode.key.equals(key))
{
// 如果一样 就覆盖
kvNode.value = value;
}
else{
// 如果不一样就用链表存起来
kvNode.next = node;
}
}
public V get (K key){
int hash = hash(key);
int i = (table.length - 1 ) & hash;
Node<K,V> node = table[i];
if(node == null)
{
return null;
}
Node<K,V> newNode = node; // 做条件判断
// 如果存在这个值 而且存在hash冲突 那就需要去循环这个链表 直到找到那个key
while (node.next != null)
{
if (newNode.key.equals(key)){
// 这就说明找到了 直接跳出循环
break;
}else{
newNode=newNode.next; // 如果找不到key 就一直往链表的后面找
}
}
return newNode.value; // 最后返回这个值
}
/**
* 计算哈希值
* @param key
* @return
*/
static final int hash(Object key){
int h;
return (key == null)? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public static void main(String[] args) {
MyHashTable<String,String> hashTable = new MyHashTable<String, String>(5);
hashTable.put("key1","ycw");
hashTable.put("key2","ycw2");
hashTable.put("key1","ycw3");
System.out.println(hashTable.get("key1"));
System.out.println(hashTable.get("key2"));
}
}
2.2、hashmap
扩容
在填装因子(loaderFactor) > 0.75 时进行扩容
- 创建新的数组,长度newLength是原来的2倍(将哈希表的存储空间增加为原来的两倍)。
- 遍历旧列表中取出元素的key之后,重新进行hash计算 newndex = (newLength- 1) & hash。
- 重新插入元素。
Java实现哈希表的更多相关文章
- Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...
- JAVA数据结构--哈希表的实现(分离链接法)
哈希表(散列)的定义 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度 ...
- java数据结构----哈希表
1.哈希表:它是一种数据结构,可以提供快速的插入操作和查找操作.如果哈希表中有多少数据项,插入和删除操作只需要接近常量的时间.即O(1)的时间级.在计算机中如果需要一秒内查找上千条记录,通常使用哈希表 ...
- java数据结构——哈希表(HashTable)
哈希表提供了快速的插入操作和查找操作,每一个元素是一个key-value对,其基于数组来实现. 一.Java中HashMap与Hashtable的区别: HashMap可以接受null键值和值,而Ha ...
- java资料——哈希表(散列表)(转)
哈希表 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度. ...
- java集合-哈希表HashTable
一.简介 HashTable也是一种key-value结构,key-value不允许null,并且这个类的几乎全部的方法都加上了synchronized锁,来保证并发安全,由于加了锁所以性能方面会比较 ...
- java集合-哈希表HashMap
一.简介 HashMap是一个散列表,是一种用于存储key-value的数据结构. 二.类图 public class HashMap<K,V> extends AbstractMap&l ...
- Java数据结构——哈希表
- Java知多少(79)哈希表及其应用
哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺 ...
- 哈希表类Hashtable
哈希表是一种重要的存储方式,也是一种常见的检索方法.其基本思想是将关系码的值作为自变量,通过一定的函数关系计算出对应的函数值,把这个数值解释为结点的存储地址,将结点存入计算得到存储地址所对应的存储单元 ...
随机推荐
- ubuntu16.04 ssh启用root连接
安装好ubuntu16.04 server版默认是不允许客户端ssh工具连接root的. 启用方法如下: 1.设置root密码 dylan@ubuntu:~$ sudo passwd root [su ...
- jsp中无法识别EL表达式问题
今天在开发系统时需要在JSP中遍历List<javabean>,其中用到了EL表达式:${item.value} 页面死活不出数据,只显示表达式本身:${item.value}. 页面代码 ...
- weblogic CVE-2024-20931分析
weblogic 12.2.1.4.0安装 我的环境:ubuntu 22.04 + weblogic 12.2.1.4.0 + jdk8(注:weblogic不支持OpenJDK) jdk下载安装:h ...
- Python函数每日一讲 - 一文让你彻底掌握Python中的getattr函数
引言 在 Python 中,getattr() 函数是一种强大的工具,它允许我们在运行时动态地访问对象的属性和方法.本文将介绍 getattr() 函数的基本语法.常见用法和高级技巧,帮助大家更好地理 ...
- 【Azure 应用服务】App Service中抓取 Web Job 的 DUMP 办法
问题描述 使用Azure App Service,也可以部署一个Java程序作为Web Job运行.运行一个 .Jar 文件只需要以下4步: 1)把Java应用打包成一个 .jar 文件 2)创建一个 ...
- goland快键键防忘
环境: debian下的goland 2018实测: 鼠标button2 == 鼠标中键 光标移动: 跳转光标到刚才的位置: ctrl+win+alt+左/右 按词左右移动光标: ctrl + 左/右 ...
- python执行JavaScript代码出现编码问题的解决方案
当我们安装好nodejs环境,想在python代码中去调用JavaScript代码,常常会出现编码的问题. 举个例子: python代码如下: 点击查看代码 import execjs f = ope ...
- [Python] 子线程退出孙线程不退出
遇到了一个大坑! 如图,在子线程ThreadFunc退出之后,ThreadFunc2依旧在运行... 根本不会结束 但是官方文档中说明了,只要设置了daemon不为None 就能设置子线程是守护线程, ...
- 第18章_MySQL8其它新特性
# 目录: https://www.cnblogs.com/xjwhaha/p/15844178.html 1. MySQL8新特性概述 MySQL从5.7版本直接跳跃发布了8.0版本,可见这是一个令 ...
- XSS漏洞原理整理
一.通常使用XSS脚本来获取浏览器版本信息,alert(navigator.userAgnet ) ,浏览器的UserAgent是可以伪造的,比方火狐或者很多扩展都可以屏蔽或者自定义浏览器发送的Us ...