JAVA 集合进阶 Map集合的实现类 TreeMap
1 TreeMap
- TreeMap 跟 TreeSe t底层原理一样,都是红黑树结构的。
- 由键决定特性:不重复、无索引、可排序
- 可排序:对键进行排序。
- 注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
1.1 代码书写两种排序规则
- 实现 comparable 接口,指定比较规则。
- 创建集合时传递 comparator 比较器对象指定比较规则。
2 TreeMap 练习
2.1 练习一
键:整数表示id
值:字符串表示商品名称
要求:按照id的升序排列、按照id的降序排列
升序
package com.bjpowernode.test20;import java.util.TreeMap;public class TreeMapDemo1 {public static void main(String[] args) {//创建集合对象TreeMap<Integer, String> treeMap = new TreeMap<>();//向集合中添加元素treeMap.put(5, "水杯");treeMap.put(4, "耳机");treeMap.put(3, "手机");treeMap.put(2, "电脑");treeMap.put(1, "文具");//打印集合//默认会按照键的升序进行排列//IntegerDouble默认情况下都是按照升序排列的//String按照字母再AscII码表中对应的数字升序进行排列System.out.println(treeMap); //{1=文具, 2=电脑, 3=手机, 4=耳机, 5=水杯}}
}
运行结果:
降序
package com.bjpowernode.test20;import java.util.Comparator;
import java.util.TreeMap;public class TreeMapDemo2 {public static void main(String[] args) {//按照 ID 降序排列//创建集合对象TreeMap<Integer, String> treeMap = new TreeMap<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {//o1:当前要添加的元素//o2:表示已经在红黑树中存在的元素return o2 - o1; //会按照降序输出!!}});//向集合中添加元素treeMap.put(5, "水杯");treeMap.put(4, "耳机");treeMap.put(3, "手机");treeMap.put(2, "电脑");treeMap.put(1, "文具");//打印集合System.out.println(treeMap); //{5=水杯, 4=耳机, 3=手机, 2=电脑, 1=文具}}
}
运行结果:
2.2 练习二
键:学生对象
值:籍贯
要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名年龄视为同一个人
学生类
重点是对 TreeMap 的键进行自定义的排序
package com.bjpowernode.test20;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;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {// 在这里我们要指定规则//按照学生年龄的升序排列,年龄样按照姓名的字母排列,同姓名年龄视为同一个人。//this:表示当前要添加的元素//o:表示已经在红黑树中存在的元素//返回值://负数:表示当前要添加的元素是小的,存左边//正数:表示当前要添加的元素是大的,存右边//0:表示当前要添加的元素已经存在,舍弃int i = this.getAge() - o.getAge(); //用添加的学生对象的年龄 和 红黑树中已经存在的学生对象的年龄去比较i = i == 0 ? this.getName().compareTo(o.getName()) : i; // 先判断 i 的值是否为 0 ,如果是 0 (代表年龄一样),那么再按照姓名比较// 如果不是 0,那么把 i 的值再交给 ireturn i; //直接返回 i}
}
测试类
package com.bjpowernode.test20;import java.util.TreeMap;public class TreeMapDemo3 {public static void main(String[] args) {// 1 创建集合TreeMap<Student, String> treeMap = new TreeMap<>();// 2 创建三个学生对象Student s1 = new Student("张三", 23);Student s2 = new Student("李四", 25);Student s3 = new Student("王五", 21);//添加元素treeMap.put(s1, "南京");treeMap.put(s2, "杭州");treeMap.put(s3, "洛阳");//打印集合System.out.println(treeMap); // 因为 TreeMap 会默认对键排序,而我们传入的是自定义对象// 如果不再自己定义键的排序方法,则会报错}
}
运行结果:
2.3 练习三
字符串“aababcabcdabcde"
请统计字符串中每一个字符出现的次数,并按照以下格式输出
输出结果:a(5)b(4)c(3)d(2)e(1)
package com.bjpowernode.test20;import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.function.BiConsumer;public class TreeMapDemo4 {public static void main(String[] args) {//新的统计思想:利用 Map 集合进行统计//如果题目中没有要求对结果进行排序,默认使用 HashMap//如果题目中要求对结果进行排序,请使用 TreeMap//定义字符串String s = "aababcabcdabcde";//创建集合TreeMap<Character, Integer> treeMap = new TreeMap<>();//遍历字符串for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);//拿着 c 到集合中判断是否存在if(treeMap.containsKey(c)){ //存在int count = treeMap.get(c);count++;treeMap.put(c, count);} else {treeMap.put(c, 1);}}//4 遍历集合Set<Map.Entry<Character, Integer>> entries = treeMap.entrySet();for (Map.Entry<Character, Integer> entry : entries) {System.out.print(entry.getKey() + "(" + entry.getValue() + ")");}System.out.println();// 4 以上字符串拼接,可以使用 StringBuilderStringBuilder sb = new StringBuilder();treeMap.forEach(new BiConsumer<Character, Integer>() { // 这个匿名内部类还可以省略@Overridepublic void accept(Character key, Integer value) {sb.append(key).append("(").append(value).append(")");}});System.out.println(sb);// 4 以上字符串拼接,可以使用 StringJoinerStringJoiner sj = new StringJoiner("", "", "");treeMap.forEach(new BiConsumer<Character, Integer>() { // 这个匿名内部类还可以省略@Overridepublic void accept(Character key, Integer value) {sj.add(key + "").add("(").add(value + "").add(")");}});System.out.println(sj);}
}
运行结果:
3 总结
3.1 TreeMap集合的特点是怎么样的?
- 不重复、无索引、可排序
- 底层基于红黑树实现排序,增删改查性能较好
3.2 TreeMap集合排序的两种方式
- 实现 comparable 接口,指定比较规则
- 创建集合时传递 Comparator 比较器对象指定比较规则
参考链接:
集合进阶-10-TreeMap的基本使用和基础练习1_哔哩哔哩_bilibili
集合进阶-11-TreeMap练习2-键位置添加自定义对象_哔哩哔哩_bilibili