LinkedHashMap和TreeMap的基本使用

2024-08-27 20:44

本文主要是介绍LinkedHashMap和TreeMap的基本使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.LinkedHashMap集合:(是HashMap集合的儿子,Map集合的孙子)

1.特点:

2.代码实现:

1)键的唯一性:
package com.itheima.a01myMap;
​
import java.util.LinkedHashMap;
​
public class A07_LinkedHashMapDemo3 {public static void main(String[] args) {//1.创建集合LinkedHashMap<String,Integer> lhm=new LinkedHashMap<>();
​//2.添加元素lhm.put("a",123);lhm.put("a",123);lhm.put("b",456);lhm.put("c",789);
​//3.打印集合System.out.println(lhm);/* 运行结果为{a=123, b=456, c=789}添加了两个"a",123 ,但集合中只有一个"a",123 ,因为键是唯一的,不能重复,但值可以重复(和Map集合一样)*/}
}
​
2)键相同时,值不同->添加时以后来添加的为准:(添加元素的put方法有两个功能:添加,覆盖)
package com.itheima.a01myMap;
​
import java.util.LinkedHashMap;
​
public class A07_LinkedHashMapDemo3 {public static void main(String[] args) {//1.创建集合LinkedHashMap<String,Integer> lhm=new LinkedHashMap<>();
​//2.添加元素lhm.put("a",123);lhm.put("a",111);lhm.put("b",456);lhm.put("c",789);
​//3.打印集合System.out.println(lhm);/* 运行结果为{a=111, b=456, c=789}*/}
}
​

二.TreeMap集合:(Map集合的儿子)

1.特点与排序规则:

2.代码实现:(练习)

需求1:

键:整数表示id

值:字符串表示商品名称

要求:按照id的升序排列和按照id的降序排列

  • 按照id的升序排列:id为整型,属于基本数据类型,默认升序排列,所以无需重写比较规则

    package com.itheima.a02myTreeMap;
    ​
    import java.util.TreeMap;
    ​
    public class A01_TreeMapDemo1 {public static void main(String[] args) {//1.创建集合对象TreeMap<Integer,String> tm=new TreeMap<>();
    ​//2.添加元素tm.put(1,"奥利奥");tm.put(5,"可口可乐");tm.put(2,"康师傅");tm.put(4,"雪碧");tm.put(3,"六个核桃");
    ​//3.打印集合System.out.println(tm);//运行结果为{1=奥利奥, 2=康师傅, 3=六个核桃, 4=雪碧, 5=可口可乐}}
    }

    Integer类里比较规则compare方法:

  • 按照id的降序排列:id为整型,属于基本数据类型,默认升序排列,但此时要降序排列,

    因此要重写比较规则-->要用到匿名内部类

    package com.itheima.a02myTreeMap;
    ​
    import java.util.Comparator;
    import java.util.TreeMap;
    ​
    public class A01_TreeMapDemo1 {public static void main(String[] args) {//1.创建集合对象TreeMap<Integer,String> tm=new TreeMap<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {//o1:当前要添加的元素//o2:表示已经在红黑树中存在的元素return o2-o1;/* 返回o1-o2为升序排列返回o2-o1为降序排列如果忘了,返回o1-o2和返回o2-o1挨个试就知道各自的排序规则了*/}});
    ​//2.添加元素tm.put(1,"奥利奥");tm.put(5,"可口可乐");tm.put(2,"康师傅");tm.put(4,"雪碧");tm.put(3,"六个核桃");
    ​//3.打印集合System.out.println(tm);//运行结果为{5=可口可乐, 4=雪碧, 3=六个核桃, 2=康师傅, 1=奥利奥}}
    }
    ​

需求2:

键:学生对象

值:籍贯

要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名同年龄视为同一个人。

  • Student类:

    package com.itheima.a02myTreeMap;
    ​
    public class Student implements Comparable<Student>{private String name;private int age;
    ​
    ​public Student() {}
    ​public Student(String name, int age) {this.name = name;this.age = age;}
    ​/*** 获取* @return name*/public String getName() {return name;}
    ​/*** 设置* @param name*/public void setName(String name) {this.name = name;}
    ​/*** 获取* @return age*/public int getAge() {return age;}
    ​/*** 设置* @param age*/public void setAge(int age) {this.age = age;}
    ​public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
    ​@Overridepublic int compareTo(Student o) {/* this:表示当前要添加的元素形参o:表示已经在红黑树中存在的元素*//*返回值:this的减o的负数:表示当前要添加的元素是小的,存左边正数:表示当前要添加的元素是大的,存右边0:表示当前要添加的元素已经存在,则不存*/int i = this.getAge() - o.getAge();i = i==0?this.getName().compareTo(o.getName()):i;return i;}/* TreeMap集合底层是红黑树,书写比较再排序的规则无需重写hashCode和equals方法*/
    }
    ​

  • 测试类:

    package com.itheima.a02myTreeMap;
    ​
    import java.util.TreeMap;
    ​
    public class A02_TreeMapDemo2 {public static void main(String[] args) {//1.创建集合TreeMap<Student,String> tm=new TreeMap<>();/* TreeMap集合在添加元素时是要对键进行比较再排序的,本例中键属于自定义对象,并没有指定比较再排序的规则,因此要在自定义对象类下指定比较再排序规则*/
    ​//2.创建三个学生对象Student s1=new Student("zhangsan",24);Student s2=new Student("lisi",23);Student s3=new Student("wangwu",24);
    ​//3.添加元素tm.put(s1,"江苏");tm.put(s2,"天津");tm.put(s3,"北京");
    ​//4.打印集合System.out.println(tm);/*运行结果为{Student{name = lisi, age = 23}=天津, Student{name = wangwu, age = 24}=北京,Student{name = zhangsan, age = 24}=江苏}*/}
    }
    ​

    需求3:统计个数

    需求:字符串"aababcabcdabcde"

    请统计字符串中每一个字符出现的次数,并按照以下格式输出

    输出结果:

    a(5)b(4)c(3)d(2)e(1)

分析:本题有关统计:

1) 计数器思想-->不适用,因为计数器思想对于统计的数量比较多或者统计的数量未知是难以实现的

2)利用Map集合进行统计-->适用,HashMap集合和TreeMap集合,其中键表示要统计的内容,值表示次数

注:如果题目中没有要求对结果进行排序,默认使用HashMap集合,

如果题目中要求对结果进行排序,则使用TreeMap集合

本题结果是升序的(字母ASCII码升高的顺序)-->使用TreeMap集合

(用集合的小习惯:用到了再创建,用不到则不创建)

错解:
package a36practice;
​
import java.util.Set;
import java.util.TreeMap;
import java.util.function.BiConsumer;
​
public class TreeMapDemo {public static void main(String[] args) {//1.创建集合TreeMap<Character,Integer> tm=new TreeMap<>();
​//2.字符串String str="aababcabcdabcde";
​//3.调用method方法method(str,tm);
​//4.遍历集合tm.forEach(new BiConsumer<Character, Integer>() {@Overridepublic void accept(Character key, Integer value) {System.out.println(key+"("+value+")");}});}
​//定义方法//需要字符,集合//返回集合private static TreeMap<Character,Integer> method(String str,TreeMap<Character,Integer> tm){//1.遍历集合的键看是否有字符cSet<Character> keys = tm.keySet();for (Character key : keys) {//2.遍历字符串,依次判断哪一个字符与外循环(遍历集合)的键匹配/* 一个键上就要把字符串的某一个字符全部统计完因此键在外循环,字符为内循环*/for (int i = 0; i < str.length(); i++) {//3 获取指定索引上的字符Character c=str.charAt(i);//4.键为key,进行判断if (tm.containsKey(c)) { //判断条件不是key==c,而是tm.containsKey(c)-->键上是否有c//代表已有,键不动,值加1即可Integer value = tm.get(key);value++;//集合添加-->别忘了这步tm.put(c, value);} else {//代表键不存在,给键赋c,值为1-->因为第一次出现tm.put(c, 1);/*key=c;Integer value = tm.get(key);value++; 这么写不对,value++就不对*/}}}return tm;}
}
​

错误原因:方法method里Set<Character> keys = tm.keySet();就有问题,因为第一次执行时集合tm长度为0,键为空,因此Set<Character>就为空,导致for (Character key : keys)循环不了。


正解:遍历方式有三种

第一种:利用StringBuilder类里的append方法实现拼接

package com.itheima.a02myTreeMap;
​
import java.util.TreeMap;
import java.util.function.BiConsumer;
​
public class A03_TreeMapDemo3 {public static void main(String[] args) {//1.定义字符串String s="aababcabcdabcde";
​//2.创建集合TreeMap<Character,Integer> tm=new TreeMap<>();
​//3.遍历字符串得到里面的每一个字符for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);/* 拿着c(c代表字符串里的某个字符)到集合中判断是否存在存在,表示当前字符又出现了一次不存在,表示当前字符是第一次出现*/if(tm.containsKey(c)){//存在//先把存在的这个字符已经出现的次数拿出来Integer count = tm.get(c);//这个代表把次数拿出来再赋值给count,第二次循环不会清除之前的数,更不会弄为0//当前字符又出现了一次,则自增count++;//把自增之后的结果再添加到集合当中tm.put(c,count);}else {//不存在/* 给键赋值。值为1,因为第一次出现再添加到集合中*/tm.put(c,1);}}
​/* //4.打印集合System.out.println(tm);//运行结果为{a=5, b=4, c=3, d=2, e=1}上述打印方式不符合题目要求-->可通过遍历解决*/
​//4.遍历集合,并按照指定的格式拼接即 a(5)b(4)c(3)d(2)e(1)StringBuilder sb=new StringBuilder();
​tm.forEach(new BiConsumer<Character, Integer>() {@Overridepublic void accept(Character key, Integer value) {sb.append(key).append("(").append(value).append(")");}});
​System.out.println(sb);}
}

第二种:利用StringJoiner类里的add方法实现拼接

package com.itheima.a02myTreeMap;import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.function.BiConsumer;public class A03_TreeMapDemo3 {public static void main(String[] args) {//1.定义字符串String s="aababcabcdabcde";//2.创建集合TreeMap<Character,Integer> tm=new TreeMap<>();//3.遍历字符串得到里面的每一个字符for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);/* 拿着c(c代表字符串里的某个字符)到集合中判断是否存在存在,表示当前字符又出现了一次不存在,表示当前字符是第一次出现*/if(tm.containsKey(c)){//存在//先把存在的这个字符已经出现的次数拿出来Integer count = tm.get(c);//这个代表把次数拿出来再赋值给count,第二次循环不会清除之前的数,更不会弄为0//当前字符又出现了一次,则自增count++;//把自增之后的结果再添加到集合当中tm.put(c,count);}else {//不存在/* 给键赋值。值为1,因为第一次出现再添加到集合中*/tm.put(c,1);}}/* //4.打印集合System.out.println(tm);//运行结果为{a=5, b=4, c=3, d=2, e=1}上述打印方式不符合题目要求-->可通过遍历解决*///4.遍历集合,并按照指定的格式拼接即 a(5)b(4)c(3)d(2)e(1)StringJoiner sj=new StringJoiner("","","");/*创建StringJoiner对象时形参要指定开始标记,结束标记和间隔符号本例中开始标记,结束标记和间隔符号全用长度为0的字符串*/tm.forEach(new BiConsumer<Character, Integer>() {@Overridepublic void accept(Character key, Integer value) {sj.add(key+"").add("(").add(value+"").add(")");/* StringJoiner类里的add方法的参数必须是字符串,若不是字符串,则在后面加双引号即""即可*/}});System.out.println(sj);}
}

第三种:直接遍历输出

package com.itheima.a02myTreeMap;import java.util.TreeMap;public class A03_TreeMapDemo3 {public static void main(String[] args) {//1.定义字符串String s="aababcabcdabcde";//2.创建集合TreeMap<Character,Integer> tm=new TreeMap<>();//3.遍历字符串得到里面的每一个字符for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);/* 拿着c(c代表字符串里的某个字符)到集合中判断是否存在存在,表示当前字符又出现了一次不存在,表示当前字符是第一次出现*/if(tm.containsKey(c)){//存在//先把存在的这个字符已经出现的次数拿出来Integer count = tm.get(c);//这个代表把次数拿出来再赋值给count,第二次循环不会清除之前的数,更不会弄为0//当前字符又出现了一次,则自增count++;//把自增之后的结果再添加到集合当中tm.put(c,count);}else {//不存在/* 给键赋值。值为1,因为第一次出现再添加到集合中*/tm.put(c,1);}}/* //4.打印集合System.out.println(tm);//运行结果为{a=5, b=4, c=3, d=2, e=1}上述打印方式不符合题目要求-->可通过遍历解决*///4.遍历集合,并按照指定的格式拼接即 a(5)b(4)c(3)d(2)e(1)tm.forEach((key,value) -> System.out.print(key+"("+value+")"));}
}

三.TreeMap集合总结:


这篇关于LinkedHashMap和TreeMap的基本使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112729

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF