哈希表的最主要优点是能够在O(1)的时间内查找到某一元素,是效率最高的查找方式,但其缺点是需要额外的空间来实现哈希表
1.添加键值对:map.put()
HashMap map=new HashMap();
map.put("zhangsan",1);
map.put("lisi",2);
map.put("wangwu",3);
2.通过key得到对应的value值,map.get()
HashMap map=new HashMap();
map.put("zhangsan",1);
map.put("lisi",2);
map.put("wangwu",3);
map.get("zhangsan")
//输出得到数字1
map.get()方法有一个升级版的map.getOrDefault()
如果hashmap里面含有这个key,就正常返回对应的value,此时map.getOrDefault()其实就等价于map.get()
如果hashmap里面没有这个key,就返回map.getOrDefault(key,default)这个default值,但是注意:此时hashmap里面并没有添加进这个键值对,也就是说你下次如果map.get(key),得到的是null
HashMap map=new HashMap();
map.put("zhangsan",1);
map.put("lisi",2);
map.put("wangwu",3);
System.out.println(map.getOrDefault("hanmeimei",4));
//返回4
System.out.println(map.containsKey("hanmeimei"));
//返回false,说明"hanmeimei:4"这个键值对确实没有被添加进hashmap里面
System.out.println(map.get("hanmeimei"));
//返回null
System.out.println(map);
//返回{lisi=2, zhangsan=1, wangwu=3}
注意:map.get()只需传入一个参数:key
而map.getOrDefault()传入两个参数, key和如果不存在这个key返回的数
在leetcode刷题过程中我们经常使用map.put()方法里面嵌套map.getOrDefault()方法来统计数组里面每个数字出现的个数
//nums是一个数组
for(int num:nums)
{
map.put(num,map.getOrDefault(num,0)+1);
}
这句话的核心就是添加键值对“num:?",也就是map.put(num,?),那么num这个key对应的value到底是多少呢?
?=map.getOrDefault(num,0)+1
也就是说如果num这个数已经是map里面的key了,?=map.get(num)+1
如果num这个数不是map里面的key,这说明是第一次统计num这个数的次数,那么?=0+1=1
不管map.getOrDefault(num,0)返回的是什么数(到底是0还是非0),都要加1
总结:map.put(num,?)
?=map.get(num,0)+1
不管map.getOrDefault(num,0)返回的是什么数(到底是0还是非0),都要加1
3.返回hashmap里面所有key组成的set集合,map.keySet()
HashMap map=new HashMap();
map.put("zhangsan",1);
map.put("lisi",2);
map.put("wangwu",3);
System.out.println(map);
//{lisi=2, zhangsan=1, wangwu=3}
System.out.println(map.keySet());
//得到一个key组成的set:[lisi, zhangsan, wangwu]
4.判断HashMap中是否含有某个key,返回值是true或者false:map.containsKey()
HashMap map=new HashMap();
map.put("zhangsan",1);
map.put("lisi",2);
map.put("wangwu",3);
System.out.println(map.containsKey("zhangsan"));
//返回true
System.out.println(map.containsKey("hanmeimei"));
//返回false
例题1:力扣 169 多数元素
class Solution
{
public int majorityElement(int[] nums)
{
HashMap<Integer,Integer> map=new HashMap();
//利用hashmap统计出数组中每个元素出现的次数
for(int a:nums)
{
map.put(a,map.getOrDefault(a,0)+1);
}
//遍历每一个key,如果出现value大于一半,返回这个key
for(int b:map.keySet())
{
if(map.get(b)>(nums.length/2))
{
return b;
}
}
return 0;
}
}
例题2 力扣 剑指offer53 在排序数组中查找数字
class Solution
{
public int search(int[] nums, int target)
{
HashMap<Integer,Integer> map=new HashMap();
//利用hashmap统计出数组中每个元素出现的次数
for(int a:nums)
{
map.put(a,map.getOrDefault(a,0)+1);
}
//遍历每一个key
for(int b:map.keySet())
{
if(target==b)
{
return map.get(b);
}
}
return 0;
}
}
例题3 力扣34 在排序数组中查找元素的第一个和最后一个位置
class Solution
{
public int[] searchRange(int[] nums, int target)
{
int[] result=new int[2];
HashMap<Integer,Integer> map=new HashMap();
//利用hashmap统计出数组中每个元素出现的次数
for(int a:nums)
{
map.put(a,map.getOrDefault(a,0)+1);
}
for(int i=0;i<nums.length;i++)
{
//如果存在这个target值
if(nums[i]==target)
{
result[0]=i;
result[1]=i+map.get(target)-1;
return result;
}
}
result[0]=-1;
result[1]=-1;
return result;
}
}
力扣137 只出现一次的数字||
class Solution
{
public int singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int x : nums)
{
map.put(x, map.getOrDefault(x, 0) + 1);
}
for (int x : map.keySet())
{
if (map.get(x) == 1) return x;
}
return -1;
}
}
另外TreeMap,内部会对key进行排序:(对key而不是value进行排序)
public class Main
{
public static void main(String[] args)
{
Map<String, Integer> map = new TreeMap<>();
map.put("orange", 1);
map.put("apple", 2);
map.put("pear", 3);
for (String key : map.keySet())
{
System.out.println(key);
}
// apple, orange, pear
}
}
力扣1189 气球的最大数量
用hashmap记录字符串中每个字母出现的次数
class Solution
{
public int maxNumberOfBalloons(String text)
{
if(text.contains("b")==false||text.contains("a")==false||text.contains("l")==false||text.contains("o")==false||text.contains("n")==false) return 0;
HashMap<Character,Integer> map=new HashMap();
for(int i=0;i<text.length();i++)
{
char temp=text.charAt(i);
map.put(temp,map.getOrDefault(temp,0)+1);
}
int m=map.get('b');
int n=map.get('a');
int x=map.get('l')/2;
int y=map.get('o')/2;
int z=map.get('n');
int result=Integer.MAX_VALUE;
if(result>m) result=m;
if(result>n) result=n;
if(result>x) result=x;
if(result>y) result=y;
if(result>z) result=z;
return result;
}
}
这里要注意如果没有某个字母,那么map.get("b")就等于null,而不是0
力扣49 字母异位词分组
class Solution
{
public List<List<String>> groupAnagrams(String[] strs)
{
//分组,属于同一个字母异位词的字符串放到一组
//解法:字符串转字符数组,然后再进行排序
Map<String,List<String>> map=new HashMap();
for(String str:strs)
{
//将字符串转为字符数组
char[] array=str.toCharArray();
Arrays.sort(array);//比如ate,eat排完就都是aet
String key=new String(array);//又把字符数组转回字符串,此时"aet”就是hashmap里面的key
if(map.get(key)==null)
{
map.put(key,new ArrayList<String>());//这个map非常有意思,key是字符串(比如"aet"),value是一个ArrayList,里面存["ate",”eat“,"tea"]
}
map.get(key).add(str);
}
//最后返回hashmap的value部分就行
return new ArrayList(map.values());
}
}