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

相关文章

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

oracle DBMS_SQL.PARSE的使用方法和示例

《oracleDBMS_SQL.PARSE的使用方法和示例》DBMS_SQL是Oracle数据库中的一个强大包,用于动态构建和执行SQL语句,DBMS_SQL.PARSE过程解析SQL语句或PL/S... 目录语法示例注意事项DBMS_SQL 是 oracle 数据库中的一个强大包,它允许动态地构建和执行

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详