4.5.6 Map接口

文章介绍了Java中的Map接口,包括其概述、特点、继承结构、常用方法以及如何遍历Map集合。通过案例展示了Map的使用,如统计字符串中字符出现次数,并讨论了如何确保Map集合不被修改,提出了使用unmodifiableMap方法来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



1.概述

Java.util接口Map<K,V>
类型参数 : K - 表示此映射所维护的键 V – 表示此映射所维护的对应的值
也叫做哈希表、散列表. 常用于键值对结构的数据.其中键不能重复,值可以重复
在这里插入图片描述

2.特点

  1. Map可以根据键来提取对应的值
  2. Map的键不允许重复,如果重复,对应的值会被覆盖
  3. Map存放的都是无序的数据
  4. Map的初始容量是16,默认的加载因子是0.75

在这里插入图片描述

TIPS:源码摘抄:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
初始容量1<<4,相当于1
(2^4),也就是16
static final float DEFAULT_LOAD_FACTOR = 0.75f;
默认的加载因子是0.75f,也就是存到75%开始扩容,按照2的次幂进行扩容
*

3.继承结构

在这里插入图片描述

4.常用方法

学习Map接口中的方法即可:

  • int hashCode() :返回此映射的哈希码值
  • void clear() :从此映射中移除所有映射关系(可选操作)
  • boolean containsKey(Object key) :如果此映射包含指定键的映射关系,则返回 true
  • boolean containsValue(Object value) :如果此映射将一个或多个键映射到指定值,则返回 true
  • boolean equals(Object o) :比较指定的对象与此集合是否相等
  • boolean isEmpty() :如果此映射未包含键-值映射关系,则返回 true
  • int size() :返回此映射中的键-值映射关系数
  • V get(Object key) :返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null
  • V put(K key, V value) :将指定的值与此映射中的指定键关联(可选操作),如果指定键已有对应的值,将会替换
  • void putAll(Map<? extends K,? extends V> m):从指定映射中将所有映射关系复制到此映射中(可选操作)
  • V remove(Object key) :如果存在一个键的映射关系,则将其从此映射中移除(可选操作)
  • Collection values() :将map集合中所有value存入Collection 中,并返回Collection 集合
  • Set keySet() :将map集合中所有value存入Set中,并返回Set集合
  • Set<Map.Entry<K,V>> entrySet() :将map集合中所有key和value存入Set中,并返回Set集合
package partThree;

import java.util.*;
/* 本类用于测试map接口*/
public class TestMap {
    public static void main(String[] args) {
        //1.创建MAP对象
        Map<Integer,String> map = new HashMap();
        map.put(9527,"白骨精");
        map.put(9528,"黑熊精");
        map.put(9529,"鲤鱼精");
        map.put(9530,"黄毛精");
        map.put(9531,"黑熊精");
        map.put(9527,"女儿国国王");
        System.out.println(map);
        /*
        1.map中存放的都是无序的数据,
        2.map中的value可以重复,比如我们放入了俩个黑熊精
        3.map中的key不能重复,如果重复,新的会将旧的覆盖掉
        */

        //2.进行方法测试
        //map.clear();//清空集合
        System.out.println(map.hashCode());//474360095 获取集合的哈希码
        System.out.println(map.equals("黄毛精"));//false  判断“黄毛精”是否与集合对象相等
        System.out.println(map.isEmpty());//false  判断集合是否为空
        System.out.println(map.size());//5  获取集合中键值对的个数

        System.out.println(map.containsKey(9527));//true 判断当前map集合中是否包含指定的Key键
        System.out.println(map.containsValue("黑熊精"));//true 判断当前map集合中是否包含指定的Value

        System.out.println(map.get(9527));//女儿国国王 根据key值获取到对应的value值
        System.out.println(map.remove(9529)); //鲤鱼精 根据此key值删除对应指定的键值对,key值(键)与Value(值)都删了
        System.out.println(map.containsKey(9529)); //false
        System.out.println(map.containsValue("鲤鱼精")); //false

        //将map集合中的所有value取出,放入Collection集合中
        //Collection<Type>中Type的类型,取决于map中value的类型
        Collection<String> values = map.values();
        System.out.println(values);//[女儿国国王, 黑熊精, 黄毛怪, 黑熊精]

        //将map集合中所有value存入Set中,并返回Set集合
        Set<Integer> keySet = map.keySet();
        System.out.println(keySet);//[9527, 9528, 9530, 9531]

        //将map集合中所有key和value存入Set中,并返回Set集合
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        System.out.println(entrySet);//[9527=女儿国国王, 9528=黑熊精, 9530=黄毛精, 9531=黑熊精]


    }
}

5.Map集合遍历

map集合并没有迭代器,所以除了选择for循环遍历外,只能通过先转为set集合再进行遍历,而这也是大多数人的选择,后面的章节我们会介绍,set集合可以有效的去除集合元素中重复的值和内容,下边是map转set的流程图
在这里插入图片描述

器共有俩种转换方式:

  • keySet:只将map中的可以转为set集合
  • entrySet:将map中的key和value以对应关系转为Set集合
package partThree;

import java.util.*;

public class TestMapIterator {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap();
        map.put(9527,"白骨精");
        map.put(9528,"黑熊精");
        map.put(9529,"鲤鱼精");
        map.put(9530,"黄毛精");
        map.put(9531,"黑熊精");
        map.put(9527,"女儿国国王");

        //4.map集合的迭代方式一
        /**方式一:
         * 遍历map中的数据,但是map本身没有迭代器,所以需要先转换成set集合
         * Set<Key>:把map中的所有key值存入到set集合当中--keySet()*/
        //4.1将map集合中的key值取出存入set集合中,集合的泛型就是key的类型Integer
        Set<Integer> keySet = map.keySet();
        //4.2想要遍历集合就需要获取集合的迭代器
        Iterator<Integer> it = keySet.iterator();
        //4.3循环迭代集合中的所有元素
        while(it.hasNext()){//判断是否有下一个元素可以迭代
            Integer key = it.next();//拿到本轮循环中获取到的map的key
            String value = map.get(key);
            System.out.println("{"+key+","+value+"}");
        }

        /**方式二:
         * 遍历map集合,需要把map集合先转成set集合
         * 是把map中的一对键值对key&value作为一个Entry<K,V>整体放入set
         * 一对K,V就是一个Entry*/
        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
        //获取迭代器
        Iterator<Map.Entry<Integer, String>> it2 = entrySet.iterator();
        while(it2.hasNext()){//判断是否有下一个元素可迭代
            //本轮遍历到的一个Entry对象
            Map.Entry<Integer, String> entry = it2.next();
            Integer key = entry.getKey();//获取Entry中的key
            String value = entry.getValue();//获取Entry中的value
            System.out.println("{"+key+","+value+"}");
        }
    }
}

6. 案例练习:统计一个字符串中每个字符出现的个数

package partThree;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * 本类用来完成Map集合相关练习
 * 需求:提示并接收用户输入的一串字符,并且统计出每个字符出现的次数
 * */
public class TestMapNumber {
    public static void main(String[] args) {
        //1.提示用户输入要统计的字符串 
        System.out.println("请输入您要统计的字符串");
        //2.接收用户输入的要统计的字符串
        String input = new Scanner(System.in).nextLine();
        //3.获取到用户输入的每个字符,String底层维护的是char[]
        //创建map集合存放数据,格式:{b=2,d=4,g=3}
        /**统计的是每个字符出现的次数,所以字符是char类型,次数是int,但是不可以使用基本类型,需要使用包装类型*/
        Map<Character,Integer> map = new HashMap();

        //开始位置:0 - 数组的第一个元素
        //结束位置:<input.length() 或者 <=input,length()-12
        //如何变化:++
        for (int i = 0; i < input.length(); i++) {
            char key = input.charAt(i);//获取一串字符中指定位置上的字符
            System.out.println("获取到的第"+(i+1)+"个字符:"+key);

            //4.统计每个字符出现的个数,存起来,存到map
            Integer value = map.get(key);//要先拿着key到map中找是不是有value
            if(value == null) {//如果判断为null,说明之前没有存过这个字符
                map.put(key, 1);//把当前的字符作为key存入,次数存1
            }else {
                map.put(key,value+1);//如果存过值,给之前的次数+1
            }
        }
        System.out.println("各个字符出现的频率为:");
        System.out.println(map);
    }
}

7.怎么确保一个集合不能被修改?

我们很容易想到用final关键字进行修饰,我们都知道final关键字可以修饰类,方法,成员变量,final修饰的类不能被继承,final修饰的方法不能被重写,final修饰的成员变量必须初始化值,如果这个成员变量是基本数据类型,表示这个变量的值是不可改变的,如果说这个成员变量是引用类型,则表示这个引用的地址值是不能改变的,但是这个引用所指向的对象里面的内容还是可以改变的。

那么,我们怎么确保一个集合不能被修改?首先我们要清楚,集合(map,set,list…)都是引用类型,所以我们如果用final修饰的话,只能保证表示这个引用的地址值是不能改变的,集合里面的内容还是可以修改的。

我们可以做一个实验:
在这里插入图片描述

可以看到:我们用final关键字定义了一个map集合,这时候我们往集合里面传值,第一个键值对1,1;我们再修改后,可以把键为1的值改为100,说明我们是可以修改map集合的值的。

那我们应该怎么做才能确保集合不被修改呢?

我们可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map是不可以修改的。他会报java.lang.UnsupportedOperationException错。

在这里插入图片描述

同理:Collections包也提供了对list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值