Map及Set的总结

首先要清楚这两个都是数据结构,就像是两个容器,应用场景:专门用来搜索。Tree就是一个二叉搜索树,Map和Set是两个容器,可以存放数据。Map是一个单独的接口,Set接口是拓展了collection接口的。

二叉搜索树的概念:左树节点值比根节点值小,右树的节点值比根节点大,每颗子树又是一颗搜索树。

Map:是一个单独的接口类,里边存放的数据结构是K-V键值对的方式。(key-value),也就是说每一个key值都对应的有一个value值。

所以我们可以用Map接口new一个对象看一下Map中这些方法是如何使用以及在什么情况下使用Map或者Set。

public static void main1(String[] args) {
        /*Map是一个接口,用接口的引用创建一个对象,treeMap底层是一个搜索树
        * */
        Map<String,Integer> treeMap= new TreeMap<>();
        treeMap.put("hello",3);//往里边存放数据,Key-value的形式存储
        treeMap.put("the",8);//比较的时候是用key去比较的
        treeMap.put("abc",4);
        System.out.println(treeMap);//重写了toString方法
        Integer val = treeMap.get("abc");//给一个key值,返回相对应的val值
        //如果treeMap中没有这个val值,就是null
        //还有就是如果没有这个key值可以给定一个默认值
        Integer val1 = treeMap.getOrDefault("hello44",100);
        System.out.println(val1);
        //keySet方法可以将treeMapp中存放的值进行输出,但是没有顺序,是乱序存放的
        Set<String> keySet = treeMap.keySet();
        System.out.println(keySet);
        /*Map.Entry<String,Integer>  他是一个类似节点这样的类型,就像是node,Entry是
        * 一个接口,它的里面也有方法,map也是一个接口,有点类似外部类.内部类这样,entrySet
        * 这个方法可以将里面存放的key值和value值放进另一个麻袋中,然后可以遍历这个麻袋进行
        * 输出拿到key值和value值,是Map中一个用来存放键值对的映射关系的一个内部类*/
        Set<Map.Entry<String,Integer>> set = treeMap.entrySet();
        for (Map.Entry<String,Integer> entry : set) {
            System.out.println("key: "+entry.getKey() + " value: "+entry.getValue());
        }

可以看到Map中有很多的方法:简单介绍一下几种常用的,首先是put方法,就是往map中存放数据的,以key-value键值对的方式存储,new对象的时候可以用泛型指定key和val的类型。

还可以用get方法去获取里边的数据,在get方法中给一个key值,就可以返回对应的value值,如果map中没有这个key值,就返回一个null。

getorDefault方法:给key值设置默认的value值,返回值就是给key设置的value值。

keySet方法:可以输出map中存放的key值。(一定重写了toString方法)

Map.Entry的使用:他是Map中的一个内部类,主要反应map存放的数据的k-v关系,可以用来获取键值对,然后可以设置value和key的比较方式。(它有点类似于链表中node节点这样的内部类,用的使用就是外部类.内部类,Map是一个接口,然后它也是一个接口)

 

 如上图:Entry这个接口中有这么多的方法,但是没有提供设置key的方法,因为它的底层是一颗搜索树,如果设置的key值,就要对这颗搜索树进行重新排序了,就乱了。

getKey方法:获取key值,返回key值。

getValue方法:获取value值,返回value值。

setValue方法:将key值中的value值换成自己设定的value值。

可以用Entry来输出容器中的键值对:

Set<Map.Entry<String,Integer>> set = treeMap.entrySet();
        for (Map.Entry<String,Integer> entry : set) {
            System.out.println("key: "+entry.getKey() + " value: "+entry.getValue());
        }

注:1. Map和Set都是接口,不能直接实例化对象,要实例化对象得用hashMap或者更TreeMap类来实例化对象。

2. Map中存放的key值是唯一的,就像是TreeMap中,二叉搜索树左边是比根小的,右边是比根大的,根本就没有相同的节点的说法。

3. Map中key值不能进行修改,如果要修改只能是删了重新插入。

4. Map中的key值是可以分离出来存放到Set中的,Set这个容器就是Map改了一下源码然后实现的只能存放key值。

Set:是继承collection的接口类,里边只存放K的值。(key)

 set中有这么多的方法,它的使用场景主要是对数据进行去重,因为key值是没有重复的。

(Map的使用场景主要是比如一个数据在当前数组中出现的次数,它需要用到value值来记录数组中每个数据元素出现的次数)

常用类有hashSet和TreeSet,Set中存放的key值一定是有序的。

如下图:给数据进行去重

public static void main7(String[] args) {
        //给数据去重
        int[] array = {1,3,4,5,3,5,1,2,8};
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < array.length; i++) {
            set.add(array[i]);
        }
        System.out.println(set);
     }

找到一个重复的数据:

public static void main8(String[] args) {
        //找到第一个重复的数据   最好用接口引用一个类!!!
        //因为它包含接口的方法,如果用一个集合类去引用只能使用当前类的方法
        int[] array = {1,3,4,5,3,5,1,2,8};
        Set<Integer> set = new HashSet<>();
        for (int x : array) {
            if (!set.contains(x)) {
                set.add(x);
            }else {
                System.out.println(x);
                return;
            }
        }
    }

统计数组中的重复的数据: 可以用Set来实现,也可以用Map来实现,

       Set实现就是看Set容器中有没有这个数据,如果没有就放进来,如果已经有这个数据了,就把容器中的这个数据删除。

       Map实现就是如果没有这个数据,就放进来,value值设为1,如果有这个数据了,就子啊原来的value值基础上+1.最后遍历这个容器,只输出value值>1的数据。

public static int singleNumber1(int[] nums) {
        //用Set,先遍历这个数组,如果没有这个元素,就放进来,如果没有就把这个元素删除
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            if (!set.contains(nums[i])) {
                set.add(nums[i]);
            }else {
                set.remove(nums[i]);
            }
        }
        int val = set.hashCode();//为什么hashcode方法也是可以输出set中只有一个数据的情况
        return val;
    }
public static void main9(String[] args) {
        //统计数组中 重复数据(val>=2)出现的次数?
        //key是数组中的数据,value是key这个数据在数组中出现了几次
        /*首先要清楚用哪一个容器来存储,Set容器只是存放了key值,Map容器存放了key值和value值
        * 所以用Map容器*/
        int[] array = {1,3,5,7,4,4,5,5,5,1};
        Map<Integer,Integer> map = new HashMap<>();
        for (int x : array) {//遍历数组
            if (map.get(x) == null) {
                //如果map这个容器中没有存放这个数据,就将value值设置为1
                map.put(x,1);
            }else {  //如果有,就在原来的value值的基础上+1
                //所以先看一下原来的这个value值是几,在原来的value值的基础上+1
                int val = map.get(x);
                map.put(x,val+1);
            }
        }
        for (Map.Entry<Integer,Integer> entry : map.entrySet()) {
            if (entry.getValue() > 1) {//如果重复的值的次数>1才输出它
                System.out.println("key"+entry.getKey()+" value: "+entry.getValue());
            }
        }

        //或者是用Map中的map.getOrDefault()方法
        for (int x : array) {//默认值是0,在原来的基础上去更新+1
            map.put(x,map.getOrDefault(x,0)+1);
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++中的容器有很多种,其中包括mapsetmap是一种关联容器,它存储了一组键对,每个键对应一个map中的键是唯一的,且按照某种顺序进行排序。set也是一种关联容器,它存储了一组唯一的,并按照一定的顺序进行排序。mapset都可以通过迭代器进行遍历和访问。引用、和中的代码示例展示了如何使用mapset进行操作和排序。 在示例代码中,map的键是字符串类型,是整数类型。可以使用insert函数向map中插入键对,使用[]运算符访问和修改特定键对应的set中只存储了,可以使用insert函数插入,使用find函数查找特定的。 需要注意的是,mapset中的元素是按照键的顺序进行排序的,因此在示例代码中使用了不同的排序方式。map默认是按照键的升序进行排序的,可以使用greater<int>作为模板参数,将其改为按的降序进行排序。 总结起来,C++中的mapset是用来存储一组唯一的键的容器,可以通过迭代器进行遍历和访问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++进阶之mapset](https://blog.csdn.net/qq_52433890/article/details/124850598)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良月初十♧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值