TreeMap 是 Java 集合框架中的一个基于红黑树(Red-Black Tree)实现的有序映射。红黑树是一种自平衡的二叉查找树,能够保证插入、删除和查找操作的时间复杂度为 O(log n)。TreeMap 的主要特点包括:
TreeMap 适用于需要按键有序存储的场景,例如按字母顺序或数字顺序排序的键值对集合。以下是一个基本应用的示例:
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
TreeMap treeMap = new TreeMap<>();
treeMap.put(3, "Apple");
treeMap.put(1, "Banana");
treeMap.put(2, "Cherry");
System.out.println(treeMap); // 输出: {1=Banana, 2=Cherry, 3=Apple}
}
}
以下是 TreeMap 的一些常用方法:
示例代码:
import java.util.TreeMap;
public class TreeMapMethodsExample {
public static void main(String[] args) {
TreeMap treeMap = new TreeMap<>();
treeMap.put(3, "Apple");
treeMap.put(1, "Banana");
treeMap.put(2, "Cherry");
System.out.println(treeMap.get(2)); // 输出: Cherry
System.out.println(treeMap.firstKey()); // 输出: 1
System.out.println(treeMap.lastKey()); // 输出: 3
}
}
package test._TreeMap;
import java.util.Comparator;
import java.util.TreeMap;
public class test01_TreeMap {
public static void main(String[] args) {
/*
TreeMap集合:基本应用
需求1:
键:整数表示id
值:字符串表示商品名称
要求1:按照id的升序排列
要求2:按照id的降序排列
*/
//1.创建集合对象
//Integer Double 默认情况下都是按照升序排列的
//String 按照字母用ASCII码表中对应的数字升序进行排列
//abcdefg ...
TreeMap tm = new TreeMap<>(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//2.添加元素
tm.put(1,"我的");
tm.put(2,"你的");
tm.put(3,"啊看我的啊");
tm.put(4,"答 答");
tm.put(5,"发发我");
//3.打印集合
System.out.println(tm);
}
}
如果 TreeMap 的键是自定义对象,该对象必须实现 Comparable
接口或传入一个 Comparator
对象,以确保键的可排序性。以下是一个示例:
import java.util.TreeMap;
class Person implements Comparable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return this.name.compareTo(other.name);
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
public class CustomObjectTreeMapExample {
public static void main(String[] args) {
TreeMap treeMap = new TreeMap<>();
treeMap.put(new Person("Alice", 25), "Engineer");
treeMap.put(new Person("Bob", 30), "Doctor");
treeMap.put(new Person("Charlie", 35), "Teacher");
System.out.println(treeMap);
// 输出: {Alice (25)=Engineer, Bob (30)=Doctor, Charlie (35)=Teacher}
}
}
package test._TreeMap;
public class Student implements Comparable {
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 i = this.getAge() - o.getAge();
i = i == 0 ? this.getName().compareTo(o.getName()) : i;
return i;
}
}
package test._TreeMap;
import java.util.TreeMap;
public class test02_TreeMap {
public static void main(String[] args) {
//1.创建TreeMap对象
TreeMap tm = new TreeMap<>();
//2.创建学生对象
Student s1 = new Student("bhangsan",20);
Student s2 = new Student("aisi",20);
Student s3 = new Student("wangwu",22);
//3.添加元素
tm.put(s1,"江苏");
tm.put(s2,"广州");
tm.put(s3,"深圳");
//这里的Student就是自定义的类型,没有从小到大的默认排序,需要在Student类中进行定义排序规则
//打印集合
System.out.println(tm);
}
}
如果不想修改自定义对象的类,可以通过传入 Comparator
对象来实现排序:
import java.util.Comparator;
import java.util.TreeMap;
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return name + " ($" + price + ")";
}
}
public class ComparatorTreeMapExample {
public static void main(String[] args) {
Comparator priceComparator = Comparator.comparingDouble(Product::getPrice);
TreeMap treeMap = new TreeMap<>(priceComparator);
treeMap.put(new Product("Laptop", 999.99), 10);
treeMap.put(new Product("Phone", 699.99), 20);
treeMap.put(new Product("Tablet", 399.99), 30);
System.out.println(treeMap);
// 输出: {Tablet ($399.99)=30, Phone ($699.99)=20, Laptop ($999.99)=10}
}
}
package test._TreeMap;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.function.BiConsumer;
public class test03_TreeMap {
/* 需求:
字符串“aababcabcdabcde”
请统计字符串中每一个字符出现的次数,并按照以下格式输出
输出结果:
a(5)b(4)c(3)d(2)e(1)
新的统计思想:利用map集合进行统计
如果题目中没有要求对结果进行排序,默认使用HashMap
如果题目中要求对结果进行排序,请使用TreeMap
键:表示要统计的内容
值:表示次数
*/
public static void main(String[] args) {
//1.定义字符串
String s = "aababcabcdabcde";
//3.创建集合
TreeMap tm = new TreeMap<>();
//2.遍历字符串把字符一个个取出来
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//4.开始判断字符在集合中是否存在,为统计字符次数做准备
//拿着c到集合中判断是否存在
//存在,表示当前字符又出现了一次
//不存在,表示当前字符是第一次出现
if(tm.containsKey(c)){
//存在,就把次数拿出来
int count = tm.get(c);
count++;
tm.put(c,count);
}else {
//不存在
tm.put(c,1);
}
}
//5.遍历集合,并按照格式进行拼接输出
//a(5)b(4)c(3)d(2)e(1)
StringBuilder sb = new StringBuilder();
tm.forEach((key, value)-> sb.append(key).append("(").append(value).append(")"));
System.out.println(sb);
StringJoiner sj = new StringJoiner("","","");
// sj.add()里面只能田家庵字符串,所以+""把括号里面变成字符串
tm.forEach((key, value)-> sj.add(key+"").add("(").add(value+"").add(")"));
System.out.println(sj);
}
}
以上内容涵盖了 TreeMap 的特点、基本应用、常用方法以及如何将自定义对象作为键的详细说明和代码示例。
以下是提取的文字:
1. TreeMap集合的特点是怎么样的?
- 不重复、无索引、可排序
- 底层基于红黑树实现排序,增删改查性能较好
2. TreeMap集合排序的两种方式
- 实现Comparable接口,指定比较规则
- 创建集合时传递Comparator比较器对象,指定比较规则
(比如有时候要用降序,但是Comparable接口是默认升序的,所以这时候就要用Comparator比较器了,或者说默认的一般按abcd来排序,但是现在要拿字符串的长度进行排序,那么Comparable接口就满足不了了,要用Comparator比较器来实现)