学习任务:

视频学习

Comparator接口介绍

TreeMap自定义排序测试

PbStudent类型通过Comparable接口已经实现了按学生ID升序排序,如果想降序排序只能修改Comparable接口实现的代码,所以此方法不适用灵活改变排序策略的需求。

下边介绍一种可以灵活更改排序策略的方法。在构造TreeMap类型时可以指定一个比较器,通过比较器也可以实现排序,只需要在构造TreeMap对象时传入一个比较器对象即可。

下边是TreeMap类型的构造方法,此方法有一个参数为Comparator类型。

TreeMap(Comparator<? super K> comparator) 

Comparator是一个接口,如下:

public interface Comparator<T> {
	//比较两个数
	int compare(T o1, T o2);
	...
}

int compare(T o1, T o2);方法实现两个数的比较,o1为新数,o2为旧数,每次向TreeMap集合添加一个数会拿新数比较旧数。

根据compare方法的返回值决定排序结果:

1、返回的是一个大于0的数

返回大于0的数说明新数比旧数大,最终将新数排在旧数后边。

2、返回的是一个小于0的数

返回小于0的数说明新数比旧数小,最终将新数排在旧数前边。

3、返回的是一个等于0的数

返回0说明新数与旧数相等,新数的value值替换旧数的value值。

下边通过Comparator接口实现TreeMap的排序,下边代码实现了按ID升序:

//比较器排序测试
	public static void sort4() {
		//按ID升序排序
		Comparator<PbStudent> comparator = (v1,v2)->v1.getId()-v2.getId();
		//按ID降序排序
//		Comparator<PbStudent> comparator = (v1,v2)->v2.getId()-v1.getId();
		//按年龄降序,年龄相同按ID升序
		/*Comparator<PbStudent> comparator = (v1,v2)->{
			int r = v2.getAge()-v1.getAge();
			return r!=0?r:v1.getId().compareTo(v2.getId());
		};*/
		//定义一个TreeMap集合,传入比较器对象
		Map<PbStudent,PbCourse> map = new TreeMap<PbStudent,PbCourse>(comparator);
		PbStudent pbStudent0 =new PbStudent(100, "ab", 19);
		PbStudent pbStudent1 =new PbStudent(101, "bc", 19);
		PbStudent pbStudent2 =new PbStudent(102, "ac", 20);
		PbStudent pbStudent3 =new PbStudent(103, "ba", 20);
		PbStudent pbStudent4 =new PbStudent(103, "ba", 20);
		PbCourse pbCourse0 = new PbCourse(100L, "攀博课堂-Java面向对象教程", 33);
		PbCourse pbCourse1 = new PbCourse(101L, "攀博课堂-Spring全家桶教程", 44);
		PbCourse pbCourse2 = new PbCourse(102L, "攀博课堂-SpringCloud微服务教程", 55);
		PbCourse pbCourse3 = new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66);
		PbCourse pbCourse4 = new PbCourse(104L, "攀博课堂-支付系统教程", 77);
		map.put(pbStudent0,pbCourse0);
		map.put(pbStudent1,pbCourse1);
		map.put(pbStudent2,pbCourse2);
		map.put(pbStudent3,pbCourse3);
		map.put(pbStudent4,pbCourse4);//这里向map中添加了相同的key
		map.forEach((key,value)->System.out.println(key+"  "+value));
	}

Comparator对象采用Lambda表达式实现,为:(v1,v2)->v1.getId()-v2.getId(),表示新数的ID减去旧数ID的差,当新数大于旧数返回大于0的值,新数排在后边。

输出:

PbStudent{id='100', nickname='ab', age=19}  PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33]
PbStudent{id='101', nickname='bc', age=19}  PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44]
PbStudent{id='102', nickname='ac', age=20}  PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55]
PbStudent{id='103', nickname='ba', age=20}  PbCourse [id=104, courseName=攀博课堂-支付系统教程, price=77]

使用Comparator接口的好处是可以灵活设置排序规则,更改排序规则只需要定义Comparator接口实现即可。

按价格降序排序代码如下:

//按ID降序排序
Comparator<PbStudent> comparator = (v1,v2)->v2.getId()-v1.getId();

按年龄降序,年龄相同按ID升序,代码如下:

Comparator<PbStudent> comparator = (v1,v2)->{
		int r = v2.getAge()-v1.getAge();
		return r!=0?r:v1.getId().compareTo(v2.getId());
};
提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题