基于拉链式和线性探测式散列表实现Map

本文介绍了基于散列表实现Map的方法,重点讨论了拉链式和线性探测式散列表。拉链式散列表通过链表处理冲突,而线性探测式散列表利用空位解决冲突。内容包括散列函数的实现、拉链式散列表和线性探测式散列表的插入、查询、删除等操作,以及动态调整数组大小的策略。
摘要由CSDN通过智能技术生成

程序员必读书单:https://github.com/silently9527/ProgrammerBooks

微信公众号:贝塔学Java

前言

前几篇我们一起学习了基于数组、链表、二叉树、红黑树来实现Map的操作,本篇我们将会一起来学习基于散列表来实现Map,这种方式对应着java里面的HashMap,这也是使用最多的一种方式

散列表实现Map主要分为了两个步骤:

  1. 基于散列函数将被查找键转换为数组的下标
  2. 处理散列值冲突的情况,有两种方式来处理冲突:拉链式和线性探测

散列函数

实现散列表的第一步就是需要考虑如何把一个键转换为数组的下标,这时候就需要使用到散列函数,先把键值转换成一个整数然后在使用除留余数法计算出数组的下标。每种类型的键我们都需要一个不同的散列函数。

在java中对于常用的数据类型已经实现了hashCode,我们只需要根据hashCode的值使用除留余数法即可转换成数组的下标

java中的约定:如果两个对象的equals相等,那么hashCode一定相同;如果hashCode相同,equals不一定相同。对于自定义类型的键我们通常需要自定义实现hashCode和equals;默认的hashCode返回的是对象的内存地址,这种散列值不会太好。

下面我来看看Java中常用类型的hashCode计算方式

Integer

由于hashCode需要返回的值就是一个int值,所以Integer的hashCode实现很简单,直接返回当前的value值

@Override
public int hashCode() {
    return Integer.hashCode(value);
}
public static int hashCode(int value) {
    return value;
}
Long

Java中Long类型的hashCode计算是先把值无符号右移32位,之后再与值相异或,保证每一位都用用到,最后强制转换成int值

@Override
public int hashCode() {
    return Long.hashCode(value);
}

public static int hashCode(long value) {
    return (int)(value ^ (value >>> 32));
}
Double、Float

浮点类型的键java中hashCode的实现是将键表示为二进制

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值