哈希表
散列表(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 {