引言
Map和Set是一种专门用来进行搜索的容器或数据结构,其搜索的效率与其具体化实现的子类有关。
我们在以前常见的搜索方式有
1.直接遍历,这中时间复杂度比较高,需要进行元素的比较,如果元素非常多,那么它的复杂度就很高。
2.二分查找 时间复杂度为O(log2N) 但是要求数据必须是有序的
而且以上这种方法适用于静态数据,就是一般不会对区间进行插入和删除操作了。但是现实中根据姓名查询考试成绩,或者输入名字显示身份证号码。
即 可能在查找时进行一些插入和删除的操作,即动态查找,那上述两种方式就不太适合了,本节介绍的Map和Set是一种适合动态查找的集合容器。
一.模型
一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对,所以模型会有两种:
1. 纯 key 模型,比如:
有一个英文词典,快速查找一个单词是否在词典中
快速查找某个名字在不在通讯录中
2.key-value模型 :
统计文件中每个单词出现的次数, 也就是有对应关系
二者的区别就是而
Map中存储的就是key-value的键值对,Set中只存储了Key。
二.Map的使用
Map是一个接口类,该类没有继承自Collection,该类中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复。
(一).Map的常用方法

此处讲解一下entrySet方法
当我们通过Map接口创建TreeMap的时候,由于Map存的是key-value键值对,可以理解为一一对应的关系
Map<String,Integer> treeMap = new TreeMap<>(); treeMap.put("ghi",8); //按照大小排序 treeMap.put("def",4); treeMap.put("abc",3);此处ghi对应8 def对应4 abc对应3 那么如何输出这个对应关系呢?
简而言之就像是遍历这个容器,输出对应关系
treeMap.entrySet(); 这个方法的类型是什么?
Set<Map.Entry<K, V>> entrySet() 也就是需要Set<Map.Entry<K, V>>类型的值来接受下图中set就是来接收的Set<Map.Entry<String,Integer>> set = treeMap.entrySet();
那么如何遍历呢?
Set<Map.Entry<K, V>> entrySet() 的含义如下图

遍历代码
for (Map.Entry<String,Integer> entry : set) { System.out.println(entry); //其中每个数据类型是 Map.Entry<String,Integer> }要对set进行遍历 里面的每个元素都是Map.Entry<K,V>类型
(二).注意事项
1. Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
2. Map中存放键值对的Key是唯一的,value是可以重复的
3. 在TreeMap中插入键值对时,key不能为空,否则就会抛NullPointerException异常,value可以为空。但是HashMap的key和value都可以为空。
4. Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
5. Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
6. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
三.Set的使用
Set与Map主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key。
方法
解释
boolean add(E e) 添加元素,但重复元素不会被添加成功
void clear() 清空集合
boolean contains(Object o) 判断 o 是否在集合中
Iterator<E> iterator() 返回迭代器
boolean remove(Object o) 删除集合中的 o
int size() 返回set中元素的个数
boolean isEmpty() 检测set是否为空,空返回true,否则返回false
Object[] toArray() 将set中的元素转换为数组返回
boolean containsAll(Collection<?> c) 集合c中的元素是否在set中全部存在,是返回true,否则返回
false
boolean addAll(Collection<? extends E> c) 将集合c中的元素添加到set中,可以达到去重的效果
一下是Set和Map的题目练习
public static void main1(String[] args) { //1.数组中有是个数据并且有重复的,进行去重 int[] array = {1,2,2,3,3,4,4,5,5,5}; //12345 Set<Integer> set = new HashSet<>(); for (int x : array) { set.add(x);//此函数添加元素时重复元素不会被添加成功 } System.out.println(set); } public static void main2(String[] args) { //2.找到第一个重复的字符 int[] array= {1,2,2,3,3,4,4,5,5,5}; Set<Integer> set = new HashSet<>(); for (int x: array) { if(!set.contains(x)) { //如果不包含就添加 set.add(x); } else { System.out.println(x); return; //比如找到了第二个2 直接return } } } public static void main(String[] args) { //统计数字重复出现的次数 int[] array= {1,2,2,3,3,4,4,5,5,5}; Map<Integer,Integer> map = new HashMap<>(); for (int x : array) { if(map.get(x) == null) { map.put(x,1); //第一次放进去,次数都是1 } else { int count = map.get(x); // 不是第一次放进去,取得元素下标 count值++就可以 map.put(x,count + 1); } } for ( Map.Entry<Integer,Integer> entry : map.entrySet()) { if(entry.getValue() > 1) { System.out.println("key " + entry.getKey() + " value " + entry.getValue()); } } System.out.println(map); } public static void main4(String[] args) { int[] array= {1,2,2,3,3,4,4,5,5,5}; Map<Integer,Integer> map = new HashMap<>(); //main3的另一种方法 for (int i = 0; i < array.length ; i++) { map.put(array[i],map.getOrDefault(array[i],0) + 1); } System.out.println(map); }
本文介绍了Map和Set在数据搜索中的应用,特别是它们在动态查找中的优势,以及如何通过TreeMap和HashMap实例化、entrySet方法遍历、Map和Set的特性(如唯一性和去重)和常见操作。
1201

被折叠的 条评论
为什么被折叠?



