1 Map与Set概念
1.1 搜索
Map与Set是一种专门用来进行搜索的容器与数据结构,其搜索效率与其具体的实例化子类有关
以前常见的搜索方式:
- 直接遍历,时间复杂度为O(N),元素如果比较多效率会非常慢
- 二分查找,时间复杂度为 ,但搜索前必须要求序列是有序
以上述排序比较适合静态类型的查找,即一般不会对区间进行插入和删除操作
而在实际运用当中可能需要动态的查找,比如:
- 根据姓名查询考试成绩
- 通讯录,即根据姓名查询联系方式
- 不重复集合,即需要先搜索关键字是否已经在集合中
而我们的Map与Set就是一种适合动态查找的容器集合
1.2 模型
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种:
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种:
1 纯 key 模型,比如:
有一个英文词典,快速查找一个单词是否在词典中
快速查找某个名字在不在通讯录中
2 Key-Value 模型,比如:
1 统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>
2 梁山好汉的江湖绰号:每个好汉都有自己的江湖绰号
而Map中存储的就是key-value的键值对,Set中只存储了Key。
2 Map的使用(HashMap为例)
2.1 put()方法
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hello",2); map.put("hell",1); map.put("asda",5); map.put("hello",1); System.out.println(map); } }
运行结果:
{asda=5, hello=1, hell=1}
1 put方法是将键值对存放到HashMap中
2 对于重复放入的数据,后面的数据会将前面的数据掩盖掉
3 对于放入的数据前后是哈希表底层决定的,不是后放的就可以先出
2.2 remove()方法
删除Key对应的映射关系
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); map.remove("hell"); System.out.println(map); } }
运行结果:
{asda=5}
2.3 get()方法
返回key对应的value
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); int value = map.get("hell"); System.out.println(value); } }
运行结果:
1
2.4 getOrDefault()方法
返回 key 对应的 value,key 不存在,返回默认值,默认值是可以我们自己设置的
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); int value1 = map.getOrDefault("hell",0); int value2 = map.getOrDefault("hello",1); System.out.println(value1); System.out.println(value2); } }
运行结果:
1
1
2.5 entrySet()方法
函数返回值类型为:Set<Map.Entry<K, V>>,返回所有的 key-value 映射关系
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); Set<Map.Entry<String,Integer>> set = map.entrySet(); System.out.println(set); } }
运行结果:
[asda=5, hell=1]
Map.Entry<K,V>获取Key的值
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); Set<Map.Entry<String,Integer>> set = map.entrySet(); for (Map.Entry<String,Integer> tmp:set) { System.out.print(tmp.getKey()+" "); } } }
运行结果:
asda hell
Map.Entry<K,V>获取value的值
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); Set<Map.Entry<String,Integer>> set = map.entrySet(); for (Map.Entry<String,Integer> tmp:set) { System.out.print(tmp.getValue()+" "); } } }
运行结果:
5 1
Map.Entry<K,V>更改value的值
public class test1 { public static void main(String[] args) { Map<String,Integer> map = new HashMap<>(); map.put("hell",1); map.put("asda",5); Set<Map.Entry<String,Integer>> set = map.entrySet(); for (Map.Entry<String,Integer> tmp:set) { tmp.setValue(54); System.out.print(tmp.getValue()+" "); } } }
运行结果:
54 54
注意: Map.Entry<K,V>并没有提供设置Key的方法
2.6 Map要点
- Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
- Map中存放键值对的Key是唯一的,value是可以重复的
- 在Map中插入键值对时,TreeMap中key不能为空,否则就会抛NullPointerException异常,但是value可以为空,而HashMap中的Key是可以为空的
- Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
- Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
- Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行 重新插入。
3 Set的使用(HashSet为例)
3.1 add()方法
添加元素,但是重复的元素是不可以添加成功的!
public class test1 { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("hello"); set.add("hello"); set.add("well"); System.out.println(set); } }
运行结果:
[well, hello]
3.2 iterator()方法
public class test1 { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("hello"); set.add("hello"); set.add("well"); Iterator<String> it = set.iterator();//返回迭代器 while (it.hasNext()){//遍历迭代器内容 String str = it.next(); System.out.println(str); } } }
运行结果:
well
hello
3.3 toArray()方法
将set中的元素转换为数组返回
public class test1 { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("hello"); set.add("hello"); set.add("well"); Object[] str = set.toArray();//需要Object接收 for (Object e:str) { System.out.println(e); } } }
运行结果:
well
hello
3.4 Set要点
- Set是继承自Collection的一个接口类
- Set中只存储了key,并且要求key一定要唯一
- Set的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
- Set最大的功能就是对集合中的元素进行去重
- 实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
- Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新添加
- Set中不能插入null的key。
4 HashMap与HashSet对比
之后我们将利用Map与Set所学,进行有关面试题的练习!!!