26-TreeMap集合基本练习

TreeMap集合基本练习

一、练习:商品排序

需求
  • 键:整数表示id
  • 值:字符串表示商品名称
  • 要求:按照id的升序排列、按照id的降序排列

测试类
package com.app.demo31_treemap_test;

import java.util.Comparator;
import java.util.TreeMap;

public class CommodityTest1{
    public static void main(String[] args) {
        /*
            一、练习:商品排序
            需求:
                键:整数表示id
                值:字符串表示商品名称
                要求:按照id的升序排列、按照id的降序排列
                注意:默认按照键从小到大进行排序(默认升序排列),也可以自己规定键的排序规则!
                	 Integer、Double类型默认情况下都是按照升序进行排序的
                	 String类型默认情况下是按照字母在ASCII码表中对应的数字升序进行排序的
         */
        // 创建集合,键:id,值:商品名称
        // 匿名内部类
        /*TreeMap<Integer, String> tm = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 按照id进行降序排列
                return o2 - o1;
            }
        });*/
        // Lambda表达式
        TreeMap<Integer, String> tm = new TreeMap<>((o1, o2) -> o2 - o1);

        // 添加键值对元素到集合中
        tm.put(3, "iphone14");
        tm.put(1, "huawei");
        tm.put(2, "shoubiao");

        // 遍历集合
        tm.forEach((id, name) -> System.out.println(id + "=" + name));
    }
}

测试结果
3=iphone14
2=shoubiao
1=huawei

Process finished with exit code 0



二、练习:学生排序

需求
  • 键:学生对象
  • 值:籍贯
  • 要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名、年龄视为同一个人。

学生类
package com.app.demo31_treemap_test;

/*
    学生类
 */
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 + "}";
    }

    /*
        要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,
        同姓名、年龄视为同一个人。
     */
    @Override
    public int compareTo(Student o) {
        /*
        	this:表示当前要添加的元素
        	o:表示已经在红黑树中存在的元素
        	返回值:
        		负数:表示当前要添加的元素是小的,存左边
        		正数:表示当前要添加的元素是大的,存右边
        		0:表示当前要添加的元素已经存在,舍弃
       	*/
        
        // 按照学生年龄进行升序排列
        int temp = this.getAge() - o.getAge();
        // 如果年龄一样,则按照姓名的字母顺序进行排序
        temp = temp == 0 ? this.getName().compareTo(o.getName()) : temp;
        // 如果姓名、年龄都一样,则视为同一个人。
        return temp;
    }
}

测试类
package com.app.demo31_treemap_test;

import java.util.Comparator;
import java.util.TreeMap;

public class StudentTest2 {
    public static void main(String[] args) {
        /*
            练习:学生排序
            需求:
               键:学生对象
               值:籍贯
               要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名、年龄视为同一个人。

               注意:
               		1.默认按照键从小到大进行排序(默认升序排列),也可以自己规定键的排序规则!
                	  Integer、Double类型默认情况下都是按照升序进行排序的
                	  String类型默认情况下是按照字母在ASCII码表中对应的数字升序进行排序的
               	    2.如果通过实现Comparable接口的compareTo方法来指定比较规则,
                      同时又通过在创建TreeMap集合时传递Comparator比较器对象来指定比较规则,
                      那么,会默认采用第二种!
                    3.如果默认的排序规则已经无法满足当前需求时,程序运行时就会报错!此时就需要你自己指定比较规则!
         */
        // 创建集合,键:学生对象,值:籍贯
        TreeMap<Student, String> tm = new TreeMap<>((o1, o2) -> {
                // 按照学生年龄进行升序排列
                int temp = o1.getAge() - o2.getAge();
                // 如果年龄一样,则按照姓名的字母顺序进行排序
                temp = temp == 0 ? o1.getName().compareTo(o2.getName()) : temp;
                // 如果姓名、年龄都一样,则视为同一个人。
                return temp;
        });

        // 创建学生对象
        Student s1 = new Student("zhangsan", 34);
        Student s2 = new Student("lisi", 34);
        Student s3 = new Student("wangwu", 32);
        Student s4 = new Student("angelababy", 34);
        Student s5 = new Student("angelababy", 34);
        Student s6 = new Student("zhaoliu", 31);

        // 添加键值对元素到集合中
        tm.put(s1, "江苏");
        tm.put(s2, "浙江");
        tm.put(s3, "湖南");
        tm.put(s4, "黑龙江");
        tm.put(s5, "石家庄");
        tm.put(s6, "广西");

        // 遍历集合
        tm.forEach((student, s) -> System.out.println(student + "=" + s));
    }
}

测试结果
Student{name = zhaoliu, age = 31}=广西
Student{name = wangwu, age = 32}=湖南
Student{name = angelababy, age = 34}=石家庄
Student{name = lisi, age = 34}=浙江
Student{name = zhangsan, age = 34}=江苏

Process finished with exit code 0



三、练习:统计个数

需求
  • 字符串:“aababcabcdadcde”

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

  • 输出结果:

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

分析
  • 看到统计,就要想到计数器思想,但是由于统计的东西太多,计数器很不方便。

  • 因此,要有新的统计思想:利用Map集合进行统计

    如果没有要求对结果进行排序,默认使用HashMap

    如果要求对结果进行排序,使用TreeMap

    键:表示要统计的内容

    值:表示次数

  • 那么我们可以看到输出结果是:a、b、c、d、e,这样出现的,说明是需要按照字母顺序进行升序排列的。

  • 因此,要完成这个需求,就需要用到TreeMap集合

  • String类型默认情况下是按照字母在ASCII码表中对应的数字升序进行排序的。


测试类
package com.app.demo31_treemap_test;

import java.util.StringJoiner;
import java.util.TreeMap;

public class CountTest3 {
    public static void main(String[] args) {
        /*
            练习:统计个数
            需求:
                字符串:"aababcabcdabcde"
                请统计字符串中每一个字符出现的次数,并按照以下格式输出。
                输出结果:
                    a(5)b(4)c(3)d(2)e(1)

            分析:
                1.看到统计,就要想到计数器思想,但是由于统计的东西太多,计数器很不方便。
                2.因此,要有新的统计思想:利用Map集合进行统计
                3.如果没有要求对结果进行排序,默认使用HashMap
                  如果要求对结果进行排序,使用TreeMap
                  键:表示要统计的内容
                  值:表示次数
                4.那么我们可以看到输出结果是:a、b、c、d、e,这样出现的,说明是需要按照字母顺序进行升序排列的。
                  因此,要完成这个需求,就需要用到TreeMap集合。
                5.String类型默认情况下是按照字母在ASCII码表中对应的数字升序进行排序的
         */
        // 1.定义字符串
        String str = "aababcabcdabcde";

        // 3.创建TreeMap集合,键:字符,值:次数
        TreeMap<Character, Integer> tm = new TreeMap<>();

        // 2.遍历字符串,依次得到每个字符
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 4.判断当前字符是否存在于Map集合中
            if (tm.containsKey(c)) {
                // a.是,则说明存在,该字符不是第一次出现,在原有的次数上 +1
                // 根据键对象获取值对象
                int count = tm.get(c);
                // 表示该字符又出现了1次,次数+1
                count++;
                // 将新的数据添加到Map集合中
                tm.put(c, count);
            }else {
                // b.否,则说明不存在,该字符是第一次出现,记录次数为1
                tm.put(c, 1);
            }
        }

        // 5.循环结束!统计完成!遍历集合,并按照指定的格式进行拼接
        // a(5)b(4)c(3)d(2)e(1)
        // 方式1:StringBuilder
        StringBuilder sb = new StringBuilder();
        tm.forEach((key, value) -> sb.append(key).append("(").append(value).append(")"));
        // 打印结果
        System.out.println(sb);

        System.out.println("-------------------------");

        // 方式2:StringJoiner
        StringJoiner sj = new StringJoiner("", "", "");
        tm.forEach((key, value) -> sj.add(key + "").add("(").add(value + "").add(")"));
        // 打印结果
        System.out.println(sj);

        System.out.println("-------------------------");

        // 方式3:直接拼接
        tm.forEach((key, value) -> System.out.print(key + "(" + value + ")"));
    }
}

测试结果
a(5)b(4)c(3)d(2)e(1)
-------------------------
a(5)b(4)c(3)d(2)e(1)
-------------------------
a(5)b(4)c(3)d(2)e(1)
Process finished with exit code 0




四、总结

1、TreeMap集合的特点是什么?

  • 键:不重复、无索引、可排序
  • 底层基于红黑树实现排序,增删改查性能较好

2、TreeMap集合排序的两种方式什么?

  • 实现Comparable接口,指定比较规则
  • 创建集合时传递Comparator比较器对象,指定比较规则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值