Java中的Map和Set

本文介绍了Map和Set在数据搜索中的应用,特别是它们在动态查找中的优势,以及如何通过TreeMap和HashMap实例化、entrySet方法遍历、Map和Set的特性(如唯一性和去重)和常见操作。

引言

Map和Set是一种专门用来进行搜索的容器或数据结构,其搜索的效率与其具体化实现的子类有关。

我们在以前常见的搜索方式有

1.直接遍历,这中时间复杂度比较高,需要进行元素的比较,如果元素非常多,那么它的复杂度就很高。

2.二分查找 时间复杂度为O(log2N) 但是要求数据必须是有序的

而且以上这种方法适用于静态数据,就是一般不会对区间进行插入和删除操作了。但是现实中根据姓名查询考试成绩,或者输入名字显示身份证号码。

即 可能在查找时进行一些插入和删除的操作,即动态查找,那上述两种方式就不太适合了,本节介绍的MapSet是一种适合动态查找的集合容器。

 一.模型

一般把搜索的数据称为关键字(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可以为空。但是HashMapkeyvalue都可以为空。
4. Map中的Key可以全部分离出来,存储到Set来进行访问(因为Key不能重复)
5. Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)
6. Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。

三.Set的使用

SetMap主要的不同有两点: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);
    }

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值