学习任务:

视频学习

TreeMap自然排序测试1

TreeMap自然排序测试2

Comparable接口介绍

TreeMap是Map接口的一个实现类,TreeMap集合可以对key进行排序,排序方式有自然排序和比较器排序两种。

自然排序是:在构造TreeMap对象时使用它的无参构造器,在向集合添加元素(key/value对)时会调用key的compareTo方法,根据compareTo方法的值决定排序结果。

先编写一个测试代码:

package com.pbteach.javase.oop.map.test1;

import java.util.Map;
import java.util.TreeMap;


/**
 * treeMap入门测试
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class TreeMapTest2 {
	
	//自然排序测试,key为整型
	public static void sort1() {
		//定义一个map,key和value都是整型
		Map<Integer,Integer> map = new TreeMap<>();

        //添加元素,value是key的平方,故意将key的顺序打乱
		for (int i = 10; i>=6; i--) {
			map.put(i,i*i);
		}
		for (int i = 1; i <=5; i++) {
			map.put(i,i*i);
		}

		map.forEach((key,value)->System.out.println(key+"  "+value));
	}
	
	public static void main(String[] args) {
		sort1();
	}
}

输出:

1  1
2  4
3  9
4  16
5  25
6  36
7  49
8  64
9  81
10  100

从输出结果可以看出key是按照升序排列。

如果将上边程序中key改为String类型将如何排序?测试如下:

package com.pbteach.javase.oop.map.test1;

import java.util.Map;
import java.util.TreeMap;


/**
 * treeMap入门测试
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class TreeMapTest2 {
	

	//自然排序测试,key为字符串
	public static void sort2() {
		//定义一个map
		Map<String,Integer> map = new TreeMap<>();

        // 添加元素
		map.put("dc",1);
		map.put("ab",2);
		map.put("ac",3);
		map.put("bc",4);
		map.put("ba",5);

		map.forEach((key,value)->System.out.println(key+"  "+value));
	}

	public static void main(String[] args) {
		sort2();
	}
}

输出:

ab  2
ac  3
ba  5
bc  4
dc  1

从测试结果可以看出key是按照字母的音序升序排列。

TreeMap要求自然排序时key必须实现Comparable接口,上边代码key的类型为Integer、String,查看Integer的源代码发现Integer实现了Comparable接口:

public final class Integer extends Number implements Comparable<Integer> {
....
}

Comparable接口的定义如下:

public interface Comparable<T> {
	public int compareTo(T o);
}

compare方法用来对元素进行比较,每次调用TreeMap的put向集合添加一个新的数,调用此该新数的compare方法与集合中的旧数进行比较。

查看Integer类的实现方法:

image-20201016095751005

通过阅读源码可知:如果新的数小于旧数则返回-1,如果新数和旧数相等则返回0,如果新数大于旧数则返回1。

其实,方法的返回值有3种情况,3种情况决定排序结果:

1、如果新数大于旧数,返回大于0的数。

2、 如果新数小于旧数,返回小于0的数。

3、新数与旧数相等,返回等于0的数,最终新数的value值替换旧数的value值。

如果TreeMap集合中有两个相等的key,新数的value值替换旧数的value值,测试代码如下:

	//自然排序测试,key为整型
	public static void sort1_1() {
		//定义一个map,key和value都是整型
		Map<Integer,Integer> map = new TreeMap<>();

		//添加元素,value是key的平方,故意将key的顺序打乱
		for (int i = 10; i>=6; i--) {
			map.put(i,i*i);
		}
		for (int i = 1; i <=5; i++) {
			map.put(i,i*i);
		}
		//添加相同的key,value值更改为key的三次方
		for (int i = 1; i <=5; i++) {
			map.put(i,i*i*i);
		}

		map.forEach((key,value)->System.out.println(key+"  "+value));
	}

重复添加的key从1到5共5条数据,按照预期,新添加的key对应的value值将替换旧key对应的value值。

运行,输出如下:

1  1
2  8
3  27
4  64
5  125
6  36
7  49
8  64
9  81
10  100

自定义Comparable接口实现类的方法在下一个章节介绍。

提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题