【哈希表及其应用详解】

本文详细介绍了哈希表的适用场景、遍历方式和记录数组元素出现频数的方法,包括直接赋值、getOrDefault、一维数组存储和哈希集合。此外,通过实例展示了哈希表在两数之和、字母异位词判断中的应用。接着探讨了一致性哈希算法,分析了传统哈希取模的局限性,并阐述了一致性哈希算法的优势、原理以及如何处理节点增减情况。最后,简述了基于哈希表和双向链表的LRU缓存机制。
摘要由CSDN通过智能技术生成

哈希表

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
关键码值与地址一一映射

适用场景

适用于关键字与某一值一一对应,即 可使用键值对map,而hashmap是键值对中较好的实现类
关键词:一一对应

遍历哈希表的四种方式

public static void main(String[] args) {
   
    Map<String,String> map=new HashMap<String,String>();
    map.put("1", "value1");
    map.put("2", "value2");
    map.put("3", "value3");
    map.put("4", "value4");
    
    //第一种:普通使用,二次取值
    // 遍历键,取出值
    System.out.println("\n通过Map.keySet遍历key和value:");  
    for(String key:map.keySet()) {
   
        System.out.println("Key: "+key+" Value: "+map.get(key));
    }
    
    //第二种
    // 使用Map.entrySet()的迭代器
    System.out.println("\n通过Map.entrySet使用iterator遍历key和value: ");  
    Iterator map1it=map.entrySet().iterator();
    while(map1it.hasNext()) {
   
        Map.Entry<String, String> entry=(Entry<String, String>) map1it.next();
        System.out.println("Key: "+entry.getKey()+" Value: "+entry.getValue());
    }
    
    //第三种:推荐,尤其是容量大时
    // foreach
    System.out.println("\n通过Map.entrySet遍历key和value");  
    for(Map.Entry<String, String> entry: map.entrySet()) {
   
        System.out.println("Key: "+ entry.getKey()+ " Value: "+entry.getValue());
    }
    
    //第四种  
    // 遍历value
    System.out.println("\n通过Map.values()遍历所有的value,但不能遍历key");  
    for(String v:map.values()) {
   
        System.out.println("The value is "+v);
    }
 }

输出结果:

通过Map.keySet遍历key和value:
Key: 1 Value: value1
Key: 2 Value: value2
Key: 3 Value: value3
Key: 4 Value: value4
通过Map.entrySet使用iterator遍历key和value: 
Key: 1 Value: value1
Key: 2 Value: value2
Key: 3 Value: value3
Key: 4 Value: value4
通过Map.entrySet遍历key和value
Key: 1 Value: value1
Key: 2 Value: value2
Key: 3 Value: value3
Key: 4 Value: value4
通过Map.values()遍历所有的value,但不能遍历key
The value is value1
The value is value2
The value is value3
The value is value4

【推荐】使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。
说明:keySet 其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效 率更高。如果是JDK8,使用Map.foreach方法。
正例:values()返回的是V值集合,是一个list集合对象; keySet()返回的是K值集合,是一个Set集合对象; entrySet()返回的是K-V值组合集合。

记录数组中元素出现频数

遍历nums1,使用哈希表存储关键字,以及他们出现的次数

方法一:遇到空的就赋初值,非空就+1

// 1. 遍历nums1,使用哈希表存储关键字,以及他们出现的次数
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums1.length; i++) {
   
    if (map.get(nums1[i]) != null) {
   
        map.put(nums1[i], map.get(nums1[i])+1);
    } else {
   
        map.put(nums1[i], 1);
    }
}

方法二:使用getOrDefault()

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int num : nums1) {
   
    int count = map.getOrDefault(num, 0) + 1;
    map.put(num, count);
}

方法三:如果元素固定,那么我们可以就使用一个一维数组来存储他们出现的频数。这也是哈希表法。遍历字符串 p,记录字符频数

int[] sArr = new int[26];
for (int i = 0; i < p.length(); i++) {
   
    sArr[s.charAt(i) - 'a']++;  
}

方法四:如果要求元素只出现一次 或者判断是否有重复元素,那就可以用哈希集合

Set<Integer, Integer> set = new HashSet<Integer>();
for (int num : nums1) {
   
    // 添加此元素至 Set,加入失败那就代表有重复
    if(!set.add(num)) {
   
        return false;
    }
}

实例

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
你可以按任意顺序返回答案。
示例 1:输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:输入:nums = [3,3], target = 6 输出:[0,1]

答案
class Solution {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值