java数据结构14_TreeMap类使用详解

TreeMap是红黑二叉树的典型实现。我们打开TreeMap的源码,发现里面有一行核心代码:
在这里插入图片描述
root用来存储整个树的根节点。我们继续跟踪Entry(是TreeMap的内部类)的代码:
在这里插入图片描述
可以看到里面存储了本身数据、左节点、右节点、父节点、以及节点颜色。 TreeMap的put()/remove()方法大量使用了红黑树的理论。

TreeMap和HashMap用法大致相同,不同点是TreeMap可以用来排序。

HashMap和TreeMap比较:

  1. HashMap是Key无序的(key可以为null),而TreeMap是Key有序的(key不能为null)。

  2. 效率高于,在需要排序的时才选用。

  • TreeMap 默认排序

对于简单的数字、英文字母等类型,按照key的字典顺序来排序(升序)。

【示例】TreeMap 默认排序

// 创建一个TreeMap对象
TreeMap<String, Integer> map = new TreeMap<String, Integer>();
// 添加键值对
map.put("e", 55);
map.put("a", 11);
map.put("d", 44);
map.put("c", 33);
map.put("d", 44); // 只能输出一个
map.put("b", 22);
// 遍历输出map中的键和值
Set<Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Entry<String, Integer>> iterator = entrySet.iterator();
while(iterator.hasNext()) {
	Entry<String, Integer> next = iterator.next();
	System.out.println("key:" + next.getKey() + " value:" + next.getValue());
}

默认排序输出结果如下(map中的key不能重复):

key:a value:11
key:b value:22
key:c value:33
key:d value:44
key:e value:55
  • Comparable****接口排序

为什么TreeMap对String类型的key值有排序效果呢?查看String类源码可知String类实现了Comparable接口,该接口中只有一个public int compareTo(String str);方法,对象的大小关系由返回值来确定,返回负整数,零,正整数表示当前对象小于,等于,大于指定对象。
在这里插入图片描述
在这里插入图片描述
因此如果想要对自定义的对象进行排序,那么我们可以让该类实现Comparable接口, 然后实现Comparable接口的compareTo方法。

【示例】创建自定义对象 Teacher

class Teacher implements Comparable<Teacher> {
	String name;
	int age;
	public Teacher(String name, int age) {
		this.name = name;
		this.age = age;
	}
	@Override
	public int compareTo(Teacher o) {
		if(this.age > o.age) {
			return 1;  // 返回正数表示:this大于o1。 
		}else if(this.age < o.age) {
			return -1; // 返回负数表示:this小于o1。 
		}else {
			return 0;  // 返回零表示:this等于o1。 
		}
	}
}

自定义排序输出结果如下(两个王五只输出一个):

name:赵六 age:18 value:南京
name:李四 age:20 value:北京
name:王五 age:27 value:上海
name:刘七 age:29 value:深圳
name:张三 age:38 value:武汉
  • Comparator****接口排序

要想改变TreeMap的默认比较次序,我们还可以在其构造函数中传入一个自己的比较器。TreeMap的比较器构造函数如下:
在这里插入图片描述
Comparator可以对key的对象进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,返回的int值的正负表示两值的大小。

【示例】使用Comparator实现升序排序

public static void main(String[] args) {
	// 创建一个TreeMap对象
	TreeMap<Student, String> map = new TreeMap<Student, String>(new Comparator<Student>() {
		@Override
		public int compare(Student o1, Student o2) {
			if(o1.age > o2.age) {
				return 1;
			}else if(o1.age < o2.age) {
				return -1;
			}else {
				return 0;
			}
		}
	});
	// 添加键值对
	map.put(new Student("张三", 38), "武汉");
	map.put(new Student("李四", 20), "北京");
	map.put(new Student("王五", 27), "上海");
	map.put(new Student("赵六", 18), "南京");
	map.put(new Student("王五", 27), "上海"); // 只能输出一个“王五”
	map.put(new Student("刘七", 29), "深圳");
	// 遍历map	
	Set<Student> set = map.keySet();
	Iterator<Student> iterator = set.iterator();
	while(iterator.hasNext()) {
		Student stu = iterator.next();
        String key = map.get(value);
		System.out.println("name:" + stu.name + " age:" + stu.age +" key:" + key);
	}
}

自定义排序输出结果如下(两个王五只输出一个):

name:赵六 age:18 key:南京
name:李四 age:20 key:北京
name:王五 age:27 key:上海
name:刘七 age:29 key:深圳
name:张三 age:38 key:武汉
  • 使用TreeMap要点:
  1. 由于是二叉树,需要对元素做内部排序。所以要么实现Comparable接口,要么实现Comparator接口,否则会抛出java.lang.ClassCastException异常。

  2. TreeMap的key不能为null,否则抛出java.lang.NullPointerException异常。

ps:如需最新的免费文档资料和教学视频,请添加QQ群(627407545)领取。

发布了35 篇原创文章 · 获赞 0 · 访问量 354

猜你喜欢

转载自blog.csdn.net/zhoujunfeng121/article/details/104555947