JAVA集合专题4 —— Map

news2024/9/22 23:38:57

目录

      • Map接口实现类的特点
      • Map接口的常见方法
      • Map六大遍历方式
      • Map练习1
        • code
      • 编程练习2
        • code
      • 编程练习3
        • 思路
        • code

Map接口实现类的特点

  • Map与Collection并列存在,是Map集合体系的顶级接口
  • Map的有些子实现存储数据是有序的(LinkedHashMap),有些子实现存储数据是无序的(HashMap)
  • 用于保存具有映射关系的数据:Key-Value。key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
  • Map中的key和value可以是任何引用类型的数据
  • Map中的key不允许重复,原因和HashSet一样
  • Map中的value可以重复
  • Map的有些子实现允许存储null作为key(比如HashMap),有些子实现不允许存储null作为key(比如TreeMap)
  • Map的key可以为null,value也可以为null,但是key为null只能有一个,value 为null可以多个
  • 常用String类作为Map的key
package cs.kaoyan.javase.com.map;

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

public class Test1 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1","zhang san");
        map.put("no2","li si");
        map.put("no1","wang wu");//可以加入,会替换no1的zhang san
        map.put("no3","wang wu");//no.不同,可以加入

        //{no2=li si, no1=wang wu, no3=wang wu}
        System.out.println(map);

        map.put(null,null);

        //null作为key唯一,所以会替换上面作为value的null
        map.put(null,"abc");

        //null作为value可以有多个
        map.put("no4",null);
        map.put("no5",null);

        //{no2=li si, null=abc, no1=wang wu, no4=null, no3=wang wu, no5=null}
        System.out.println(map);

        //get方法,传入key,会返回对应的value
        //li si
        System.out.println(map.get("no2"));
        //wang wu
        System.out.println(map.get("no3"));
    }
}

Map接口的常见方法

package cs.kaoyan.javase.com.map;

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

public class Test3 {
    public static void main(String[] args) {
        Map map = new HashMap();

        map.put("zhang san",18);
        map.put("li si",19);
        map.put("wang wu",20);
        map.put("zhao liu",21);
        map.put("xiao qi",22);
        map.put("chang feng",23);
        map.put("tian ming",24);

        // 7
        System.out.println(map.size());
        //remove:根据键删除映射关系
        map.remove("li si");

        //get: 根据键获取值
        //22
        System.out.println(map.get("xiao qi"));
        // 6
        System.out.println(map.size());
        //False
        System.out.println(map.isEmpty());
        //True
        System.out.println(map.containsKey("tian ming"));
        //清空
        map.clear();
        // 0
        System.out.println(map.size());
    }
}

Map六大遍历方式

Map不是Iterable的子接口,也就意味着Map没有Iterator方法,所以Map没有办法法"直接"调用foreach循环

  • containsKey:查找键是否存在
  • containsValue:查找值是否存在
  • keySet:获取所有的键(获得map中key的集合视图)
  • values:获取所有的值(获得map中value的集合视图)
  • entrySet:获取所有关系(获得键值对集合)
  • get: 根据键获取值

Map练习1

假设Map中存储了一批<String,User>类型的key-value用户信息,删除User的age是18岁的同学

code

package cs.kaoyan.javase.com.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/***
 * 假设Map中存储了一批<String,User>类型的key-value用户信息
 * 删除User的age是18岁的同学
 */

public class Test5 {
    public static void main(String[] args) {
        Map<String, User> map = new HashMap<>();
        map.put("zs", new User("zs", 18));
        map.put("ls", new User("ls", 19));
        map.put("wu", new User("wu", 20));
        map.put("zl", new User("zl", 21));
        map.put("aa", new User("aa", 18));

        //删除User的age是18岁的同学
        //不可以一边遍历,一边删除,不然会出现并发修改异常ConcurrentModificationException
        //先获得key,再通过key获得value
        ArrayList list = new ArrayList();
        Set<String> allKey = map.keySet();
        for (String key : allKey) {
        	//通过key会返回一个user对象
            User user = map.get(key);
            if (user.age == 18){
                //将所有年龄为18的对象的key存入list之中
                list.add(key);
            }
        }

        //遍历list,删除key
        for (Object o : list) {
            map.remove(o);
        }

        //{zl=User{"zl",21}, ls=User{"ls",19}, wu=User{"wu",20}}
        System.out.println(map);
    }
}

编程练习2

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数, 返回它们的索引。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
比如:nums = [2, 7, 11, 15], target = 9.
因为 nums[0] + nums[1] = 2 + 7 = 9. 所以返回 [0, 1].

code

package cs.kaoyan.javase.com.map;

import java.util.Arrays;

public class Test6 {
    public static void main(String[] args) {
        int[] ints = {2,7,11,15};
        //answer数组用来存储答案
        int[] answer = {0,0};

        int target = 9;

        //方法一:暴力算法,时间复杂度O(n*n)
        /*for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (ints[i] + ints[j] == target){
                    answer[0] = i;
                    answer[1] = j;
                }
            }
        }

        System.out.println(answer[0] + " " + answer[1]);*/

        //方法二:二分算法,时间复杂度O(nlogn)
        //二分需要保证数组有序(数组本身已经有序,可以不写)
        Arrays.sort(ints);
        int size = ints.length;

        for (int i = 0; i < size; i++) {
            //在长度为size的数组ints中,找到元素target - ints[i]所在的下标
            int index2 = binarySearch(ints, size, target - ints[i]);
            if (index2 != -1){
                //存在两数之和等于target
                answer[0] = i;
                answer[1] = index2;
                //假设只有一组答案,满足即可结束循环
                break;
            }
        }

        System.out.println(answer[0] + " " + answer[1]);
    }

    /**
     * 查找元素x在数组a的下标
     * @param a:表示数组
     * @param n:表示数组的长度
     * @param x:表示要查找的目标元素
     * @return:x在数组a的下标
     */
    public static int binarySearch(int a[],int n,int x) {
        int L = 0;
        int R = n - 1;
        //ans用来记录查找要查找元素的下标(一般设置为负数)
        int ans = -1;

        //二分查找条件:L <= R
        while (L <= R) {
            int Mid = (L + R) >> 1;

            if (a[Mid] == x) {
                //查找到目标元素
                ans = Mid;
                break;
            }

            if (a[Mid] < x) {
                L = Mid + 1;
            } else {
                R = Mid - 1;
            }
        }

        //如果返回-1说明未找到要查找的目标元素x
        return ans;
    }
}

编程练习3

给你一份『词汇表』(字符串数组)words和一张『字母表』(字符串)chars。
假如你可以用chars中的『字母』(字符)拼写出words中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。注意:每次拼写时,chars中的每个字母都只能用一次。返回词汇表words中你掌握的所有单词的长度之和。
示例 1:
输入:words = [“cat”,“bt”,“hat”,“tree”], chars = “atach”
输出:6
解释:可以形成字符串 “cat” 和 “hat”,所以答案是 3 + 3 = 6。
示例 2:
输入:words = [“hello”,“world”,“leetcode”], chars = “welldonehoneyr”
输出:10
解释:可以形成字符串 “hello” 和 “world”,所以答案是 5 + 5 = 10。

思路

参考博客
遇到字符串仅包含小写(或者大写)英文字母的题,都可以试着考虑构造长度为26的数组。这样数组每个位置分别代表一个字母,统计出字母出现的次数。本题中,既要统计字母表中字母出现的次数,也要统计单词中字母出现的次数。如果字母表中字母出现的次数大于等于单词中每种字母出现的次数,那么这个单词就可以由字母表拼写出来。以字母表 "atach"和 词汇"cat"为例,过程图示如下:
在这里插入图片描述

code

package cs.kaoyan.javase.com.map;

public class Test7 {
    public static void main(String[] args) {
        String[] words = {"hello","world","leetcode"};
        String chars = "welldonehoneyr";
        int sum1 = countAllWordsLength(words, chars);
        System.out.println(sum1);//10

        String[] words2 = {"cat","bt","hat","tree"};
        String chars2 = "atach";
        int sum2 = countAllWordsLength(words2, chars2);
        System.out.println(sum2);//6

    }

    public static int countAllWordsLength (String[] words,String chars){
        int result = 0;

        int[] charsCount = count(chars);
        //遍历字符串数组
        for (int i = 0; i < words.length; i++) {
            int[] wordsCount = count(words[i]);
            //挨个判断字符串数组中的每一个字符串是否可以由给定的字符组成
            if (contains(wordsCount,charsCount)){
                //累计可以被组成的字符串的长度
                result += words[i].length();
            }
        }

        return result;
    }

    /**
     * 判断给定的字符是否可以组成字符串
     * @param stringCount:一个数组,存储待判断字符串的字母个数
     * @param charCount:一个数组,存储给定字符串的字母个数
     * @return:可以组成返回true,否则返回false
     */
    public static boolean contains(int[] stringCount,int[] charCount){
        for (int i = 0; i < 26; i++) {
            //如果待判断的字符串中某个单词出现的次数大于
            //给定字符串中某个字母出现的次数,表明不能组成这个字符串
            if (stringCount[i] > charCount[i]){
                return false;
            }
        }

        return true;
    }

    /**
     * 计算一个单词中26个字母出现的次数
     * @param s:传入一个单词
     * @return:一个整型数组
     */
    public static int[] count(String s){
        //新建一个整型数组,用来存放每个英文字母出现的次数
        int[] charCountArray = new int[26];
        //遍历字符串
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            charCountArray[(int)c - 'a'] += 1;
        }

        return charCountArray;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/341473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【量化交易】 量化因子 动量类因子

量化因子 - 风险类因子计算 5日乖离率 BIAS5 &#xff08;收盘价-收盘价的N日简单平均&#xff09;/ 收盘价的N日简单平均*100&#xff0c;在此n取5 60日变动速率&#xff08;Price Rate of Change&#xff09; ROC60 ①AX今天的收盘价—20天前的收盘价 ②BX60天前的收盘价 ③…

React-Router

版本5安装&#xff1a;npmnpm install react-router-dom5 -Syarnyarn add react-router-dom5import ReactDOM from "react-dom/client";// react router适用于web和原生项目&#xff0c;我们在web项目中使用&#xff0c;所以需要引入的包是react-router-dom import {…

Idea 安装 Sonar 插件提升代码质量

目录 0. 环境说明 1. Sonar 简介 2. IDEA 配置 Sonar 0. 环境说明 Java 1.8IDEA 2022.3.1SonarLint 7.4.0 1. Sonar 简介 在多人协通的软件开发过程中&#xff0c;代码风格和代码质量对于软件的整体交付是十分关键的。这时我们可以利用 Sonar 插件&#xff0c;对代码进行扫描…

Spring MVC注解Controller源码流程解析--HandlerAdapter执行流程--上

Spring MVC注解Controller源码流程解析--HandlerAdapter执行流程--上引言RequestMappingHandlerAdapter方法参数解析器方法参数名解析器类型转换体系简单的使用演示数据绑定器工厂定制化修改DataBinder获取泛型参数ControllerAdvice与InitBinder注解控制器方法执行流程Controll…

C语言(可变参数:stdarg.h)

目录 一.使用可变参数 1.提供一个使用省略号的函数原型 2.在函数定义中创建一个va_list类型的变量 3.用宏把该变量初始化为一个参数列表 4.用宏访问参数列表 5.使用宏完成清理工作 二.va_copy 三.实例 一.使用可变参数 该头文件提供类似接受可变数量参数的宏&#xf…

【招聘】永善县正向社会工作服务中心招聘2名工作人员

永善县正向社会工作服务中心面向社会公开招聘2名工作人员 永善县正向社会工作服务中心是2019年9月在永善县民政局注册登记成立的民办非企业单位。业务范围主要为&#xff1a;面向社会提供各类专业社工服务&#xff0c;开展活动策划、个案援助等社会服务项目&#xff1b;承接个人…

基于WEB的小型公司人事管理系统设计

技术&#xff1a;Java、JSP等摘要&#xff1a;随着当代各类企业公司员工数量越来越多、分工越来越细化、各行各业之间的联系越发密切&#xff0c;对人事管理的要求也不断提高。实现企业人事管理计算机化&#xff0c;毫无疑问会让企业的人事管理变得更加高效化和智能化。企业要生…

c/c++开发,无可避免的函数参数实践

一、函数参数表 函数由函数名以及一组操作数类型唯一地表示。函数的操作数&#xff0c;也即形参&#xff0c;在一对圆括号中声明&#xff0c;形参与形参之间以逗号分隔。每一个函数都有一个相关联的返回类型。 int setval(int val) {//函数体 }; 这里&#xff0c;定义了一个名…

Vulkan教程(14): Graphics pipeline之Fixed functions(固定管线功能)

Vulkan官方英文原文&#xff1a;https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Fixed_functions对应的Vulkan技术规格说明书版本&#xff1a; Vulkan 1.3.2The older graphics APIs provided default state for most of the stages of the graphic…

个人如何获得免费的VMware Fusion Player?在macOS上虚拟化系统

不管是开发还是测试&#xff0c;有时候都需要虚拟机。比如虚拟化一台Linux&#xff0c;部署Web服务进行服务器仿真操作。亦或者&#xff0c;macOS上虚拟化Windows&#xff0c;进行Windows环境模拟。 VMware这家公司&#xff0c;大家应该都比较熟悉。旗下的VMware Workstation在…

LabVIEW NI网络设备在MAX中不显示或未识别

LabVIEW NI网络设备在MAX中不显示或未识别有一个NI设备通过网络连接到主机。发生以下情况之一&#xff1a;尝试在Measurement&#xff06;AutomationExplorer&#xff08;MAX&#xff09;中配置设备。设备未显示在“远程系统”下。NIMAX中未检测到CompactRIO&#xff08;cRIO&a…

2D图像处理:2D Shape_Base_Matching_缩放_旋转_ICP_显示ROI

文章目录 调试结果参考调试说明问题0:并行运行问题问题1:模板+Mask大小问题问题2:组合缩放和旋转问题3:可以直接将计算边缘的代码删除问题4:如何在原始图像上显示匹配到的ROI问题5:计算的原始旋转角度不需要判断,直接可以在ICP中使用问题6:绘制坐标轴问题7:绘制ROI调试…

图像优化篇

目录&#xff08;1&#xff09;矢量图&#xff08;2&#xff09;位图 2.1 分辨率2&#xff0c;图像格式格式选择建议&#xff1a;&#xff08;1&#xff09;矢量图 被定义为一个对象&#xff0c;包括颜色&#xff0c;大小&#xff0c;形状&#xff0c;以及屏幕位置等属性&…

Netty实现Http服务器案例

功能&#xff1a;Netty服务器在6668端口监听&#xff0c;浏览器发出请求"http://localhost:6668"服务器可以恢复消息给浏览器&#xff1a;“hello&#xff0c;我是服务器”&#xff0c;并对特定请求资源进行过滤目的&#xff1a;Netty可以做服务器端开发&#xff0c;…

家政服务小程序实战教程07-轮播图组件

小程序中首页一般显示轮播图的功能&#xff0c;点击轮播图会跳转到具体的一篇文章或者是产品&#xff0c;本篇我们就介绍一下轮播图功能的开发 01 设计数据源 我们轮播图组件需要两个字段&#xff0c;一个是展示的图片&#xff0c;一个是跳转页面传入的参数。打开数据源&…

JAVA集合专题5 ——ArrayDeque + BlockingQueue

目录ArrayDeque的特点BlockingQueue什么是BlockingQueue?什么叫阻塞队列?阻塞队列的应用场景是什么?BlockingQueue的阻塞方法是什么?BlockingQueue的四类方法codecode2ArrayDeque的特点 ArrayDeque是Deque接口子实现ArrayDeque数据结构可以表示为: 队列、双端队列、栈Arra…

【MFC】工具条(16)

创建工具条的基本步骤是&#xff1a; 1.创建工具条资源。 2.构建一个CToolBar对象。 3.调用CToolBar::Create函数创建工具条窗口。 4.调用CToolBar::LoadToolBar载入工具条资源。 使用工具条 打开资源视图&#xff0c;可视化创建或者修改工具条&#xff1a; 其中ID项一般与菜…

【计组】硬盘--《深入浅出计算机组成原理》(十二)

目录 一、机械硬盘 二、SSD硬盘 &#xff08;一&#xff09;SSD硬盘的读写原理 1、SLC、MLC、TLC 和 QLC 2、P/E 擦写问题 &#xff08;二&#xff09;SSD 读写的生命周期 &#xff08;三&#xff09;磨损均衡、TRIM 和写入放大效应 1、FTL 和磨损均衡 2、TRIM 指令的…

vueday01-脚手架安装详细

一、vue脚手架安装命令npm i -g vue/cli 或 yarn global add vue/cli安装上面的工具&#xff0c;安装后运行 vue --version &#xff0c;如果看到版本号&#xff0c;说明安装成功或 vue -V工具安装好之后&#xff0c;就可以安装带有webpack配置的vue项目了。创建项目之前&#…

用队列实现栈VS用栈实现队列

之前我们就讲过队列&#xff0c;栈的基础知识&#xff0c;笔者之前有过详细的介绍&#xff0c;感兴趣的可以根据笔者的个人主页进行查找&#xff1a;https://blog.csdn.net/weixin_64308540/?typelately225. 用队列实现栈请你仅使用两个队列实现一个后入先出&#xff08;LIFO&…