本篇总结
HashMap和HashSet
👩🏻🏫作者: 初入编程的菜鸟哒哒
📚系列文章目录:一、TvT——JavaSE(1)–Java的数据类型与变量
二、TvT——JavaSE(2)–Java的运算符
三、TvT——JavaSE(3)–Java的逻辑控制
四、TvT——JavaSE(4)–Java方法的使用
五、你真的学会了JavaSE中数组的定义与使用吗?
六、Java中的类与对象来袭
七、类与对象有关static成员的知识你真的了解吗?
八、有关代码块的知识你真的了解吗?
九、初步学会JavaSE内部类知识
十、java继承真的一点也不难
十一、Java多态你学会了吗?
十二、让我们深度理解Java中的抽象类与接口
🍣1 HashMap的使用案例
HashMap
实现了Map
接口,Map
接口对键值对进行映射。
Map
中不允许出现重复的key
,value
是可以重复的。
Map
接口有两个基本的实现TreeMap
和HashMap
。
TreeMap
保存了对象的排列次序,而HashMap
不能。(HashMap的保存是根据哈希函数)
HashMap
可以有空的键值对。
import java.util.TreeMap;
import java.util.Map;
public static void TestMap(){
Map<String, String> m = new HashMap<>();
// put(key, value):插入key-value的键值对
// 如果key不存在,会将key-value的键值对插入到map中,返回null
// 注意key不能为空,但是value可以为空
// key如果为空,会抛出空指针异常
// 如果key存在,会使用value替换原来key所对应的value,返回旧value
m.put("小花", "花朵");
m.put("小草", "绿草");
m.put("猴子", "孙悟空");
m.put("小猪", "哼哼");
// get(key): 返回key所对应的value
// 如果key存在,返回key所对应的value
// 如果key不存在,返回null
System.out.println(m.get("小花"));
System.out.println(m.get("小草"))
//GetOrDefault(): 如果key存在,返回与key所对应的value,如果key不存在,返回一个默认值
System.out.println(m.getOrDefault("小花", "花花"));
System.out.println(m.getOrDefault("草草", "绿色"));
System.out.println(m.size())
//containKey(key):检测key是否包含在Map中,时间复杂度:O(logN)
// 按照红黑树的性质来进行查找
// 找到返回true,否则返回false
System.out.println(m.containsKey("小猪"));
System.out.println(m.containsKey("猪猪"));
// containValue(value): 检测value是否包含在Map中,时间复杂度: O(N)
// 找到返回true,否则返回false
System.out.println(m.containsValue("哼哼"));
System.out.println(m.containsValue("嗷呜"));
// 打印所有的键值对
// entrySet(): 将Map中的键值对放在Set中返回了
Set<Map.Entry<String,String>> entrySet = m.entrySet();
for(Map.Entry<String,String> entry : entrySet) {
System.out.println("key: "+entry.getKey()+" val:" + entry.getValue());
}
}
注意:
- Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
- Map中存放键值对的Key是唯一的,value是可以重复的
- Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
- Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
- Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
🍣2 HashSet的使用案例
HashSet:
HashSet实现了Set接口,它不允许集合中出现重复元素(通过查看hashset
的add
方法源码可以发现hashset
采用的是map
存储结构)。
当我们提到HashSet时,第一件事就是在将对象存储在HashSet之前,要确保重写hashCode()方法和equals()方法,这样才能比较对象的值是否相等,确保集合中没有储存相同的对象。
这时只要使用abstract
关键字:
import java.util.TreeSet;
import java.util.Iterator;
import java.util.Set;
public static void TestSet(){
Set<String> s = new HashSet<>();
// add(key): 如果key不存在,则插入,返回ture
// 如果key存在,返回false
boolean isIn = s.add("apple");
s.add("orange"); s.add("peach");
s.add("banana");
System.out.println(s.size());
System.out.println(s);
isIn = s.add("apple");
// add(key): key如果是空,抛出空指针异常
//s.add(null);
// contains(key): 如果key存在,返回true,否则返回false
System.out.println(s.contains("apple"));
System.out.println(s.contains("watermelen"));
// remove(key): key存在,删除成功返回true
// key不存在,删除失败返回false
// key为空,抛出空指针异常
s.remove("apple");
System.out.println(s);
s.remove("watermelen");
System.out.println(s);
Iterator<String> it = s.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
这就是抽象方法。
❗ 注意:
- Set是继承自Collection的一个接口类
- Set中只存储了key,并且要求key一定要唯一
- Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
- Set最大的功能就是对集合中的元素进行去重
通过查看
hashset
的add
方法源码可以发现hashset
采用的是map
存储结构
- 实现Set接口的常用类有
TreeSet
和HashSet
,还有一个LinkedHashSet
,LinkedHashSet
是在HashSet
的基础上维护了一个双向链表来记录元素的插入次序。- Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
- Set中不能插入null的key。
🍣3 Set和Map的区别
💌Set与Map主要的不同有两点:
Set是继承自Collection的接口类,Set中只存储了Key。 |
HashMap | HashSet |
---|---|
实现了Map接口 | 实现Set接口 |
存储键值对 | 仅存储对象 |
调用put()向map中添加元素 | 调用add()方法向Set中添加元素 |
HashMap使用键(Key)计算Hashcode | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
HashMap相对于HashSet较快,因为它是使用唯一的键获取对象 | HashSet较HashMap来说比较慢 |