小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

自然排序接口Comparable和比较器Comparator

Java,开发语言,eclipse,java 额外说明

收录于:18天前

对类实现整体排序须使用Comparable接口

看到下面的错误:

Exception in thread “main” java.lang.ClassCastException: class_chapter.StudentExample cannot be cast to java.lang.Comparable

使用TreeSet存储对象是一种自带一定规则的排序方式,但是复杂对象排序必须使用Comparable,否则会导致西安出现上述错误。

Comparable是一个接口,其中compareTo()方法定义了排序规则,可以对复杂对象进行排序。

代码部分:

//测试类
public class ComparableChapter {
	
	public static void main(String[] args) {
		
	
	TreeSet<StudentExample> ts=new TreeSet<StudentExample>();
	
	StudentExample s1=new StudentExample("s001","小明","男",20,95);
	
	StudentExample s2=new StudentExample("s002","小王","男",20,90);
	StudentExample s3=new StudentExample("s003","小花","女",21,93);
	
	ts.add(s1);
	ts.add(s2);
	ts.add(s3);
	
	for(StudentExample st1:ts) {
			System.out.println(st1);
		}
	}

//学生类
public class StudentExample{
	private String id;
	private String name;
	private String sex;
	private int age;
	private double grade;
	
	public String toString() {
		return id+"\t\t"+name+"\t\t"+sex+"\t\t"+age+"\t\t"+grade;
	}
	
	public void setId(String id) {
		this.id=id;
	}
	public String getId() {
		return this.id;
	}
	
	public void setNmae(String name) {
		this.name=name;
	}
	public String getNmae() {
		return this.name;
	}
	
	public void setSex(String sex) {
		this.sex=sex;
	}
	public String getSex() {
		return this.sex;
	}
	
	public void setAge(int age) {
		this.age=age;
	}
	public int getAge() {
		return this.age;
	}
	
	public void setGrade(double grade) {
		this.grade=grade;
	}
	public double getGrade() {
		return this.grade;
	}
	
	
	public StudentExample() {
		
	}
	public StudentExample(String id,String name,String sex,int age,double grade) {
		this.id=id;
		this.name=name;
		this.sex=sex;
		this.age=age;
		this.grade=grade;
	}

}

由于没有使用Comparable接口,所以会出现错误:Exception in thread “main” java.lang.ClassCastException: class_chapter.StudentExample cannot becast to java.lang.Comparable

// 使用Comparable接口的学生类
public class StudentExample implements Comparable{            //实现Comparable类
	private String id;
	private String name;
	private String sex;
	private int age;
	private double grade;
	
	public String toString() {
		return id+"\t\t"+name+"\t\t"+sex+"\t\t"+age+"\t\t"+grade;
	}
	
	public void setId(String id) {
		this.id=id;
	}
	public String getId() {
		return this.id;
	}
	
	public void setNmae(String name) {
		this.name=name;
	}
	public String getNmae() {
		return this.name;
	}
	
	public void setSex(String sex) {
		this.sex=sex;
	}
	public String getSex() {
		return this.sex;
	}
	
	public void setAge(int age) {
		this.age=age;
	}
	public int getAge() {
		return this.age;
	}
	
	public void setGrade(double grade) {
		this.grade=grade;
	}
	public double getGrade() {
		return this.grade;
	}
	
	
	public StudentExample() {
		
	}
	public StudentExample(String id,String name,String sex,int age,double grade) {
		this.id=id;
		this.name=name;
		this.sex=sex;
		this.age=age;
		this.grade=grade;
	}

	@Override          
	public int compareTo(java.lang.Object o) {                                  //重写compareTo方法
		// TODO Auto-generated method stub
		return 1;                                                     //1表示第二个对象比前一个打,0表示其相等,-1表示比前一个小
	}

}

由于实现了Compareble类就可以正常打印了,并按照输入的顺序输出,如果重写的compareTo()方法返回-1就会逆序输出,返回0只会输出一个,其认为后面和前面的相同。
在这里插入图片描述

对类的属性实现整体排序使用Comparator接口

上面的Comparable实现了TreeSet存储对象的整体排序。如果想按照存储对象的属性大小对对象进行排序怎么办?这里使用Comparator接口。

Comparator是一个类,compare()方法定义了复杂的排序机制来实现排序。

代码部分:

//测试类
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

import class_chapter.Student;;
public class ComparatorChapter {
	public static void main(String[] agrs) {
		
	Comparator<Student> comparator=new Comparator<Student>() {

		@Override
		public int compare(Student o1, Student o2) {
			// TODO Auto-generated method stub
				int figture1=Integer.parseInt(o1.getSid().substring(1));                  //定义的学号是S001类型要比较大小截取S后面的部分,再转化未int类型
				int figture2=Integer.parseInt(o2.getSid().substring(1));
				int sum=figture1-figture2;
				int s=sum==0? o1.compareTo(o2) : sum;                   //comparaTo()方法通过返回值来排序,三元表达式,判断学号的差值是否等于0,两种表达式。
				return s;                                               //Comparator的compare()方法和compareTo()方法一样都是通过返回值来改变排序机制,1,0,-1
			}                                                           //这里返回o1.compareTo(o2)式从小大排序,如果不等于0,是负数就比上一个小,排在前面,是正数就不上一个大在后面
		
	};
		
	Student s3=new Student("s003","小王");
	Student s2=new Student("s002","小张");
	Student s1=new Student("s001","小李");
	
	TreeSet ts1=new TreeSet(comparator);         //再创建TreeSet是需要引入Comparetor对象,对TreeSet的对象排序
	
	ts1.add(s3);
	ts1.add(s2);
	ts1.add(s1);
	
	Iterator Iterator = ts1.iterator();
	while(Iterator.hasNext()) {
		System.out.println(Iterator.next());
	}
	
	
	
	
	}
}

//学生类
public class Student{
	private String sid;
	private String sname;
	
	public String toString() {             //注意当是String类型是一定要重写tostring方法不然输出collection_and_map.Teacher@7852e922
		return sid+" "+sname;
	}	
	
	public void setSid(String sid) {
		this.sid=sid;
	}
	public String getSid() {
		return this.sid;
	}
	
	public void setSname(String sname) {
		this.sname=sname;
	}
	public String getSname() {
		return this.sname;
	}
	
	public void Student() {
		
	}
	public Student(String sid,String sname) {
		this.setSid(sid);
		this.setSname(sname);
	}

	public int compareTo(Student o2) {
		// TODO Auto-generated method stub
		return 1;                 //该方法为collection_and_map的ComparatorChapter类重写,并调用,详情见StudentExanple类
		                         //返回1,后面比前面打排在当前对象的后面,-1表示小,0表示相等。
	}
}

运行结果:
在这里插入图片描述

可以看到,添加到TreeSet中的顺序有s1,s2,s3;而输出顺序却相反,原因是创建TreeSet时引入了Comparator
改变了排序规则,使从小到大排序。

值得关注的是,Comparable,和Comparator的作用都是排序,但作用对象却不一样。他们都重写了compareTo()方法。所以要熟悉该方法。Comparator还重写了compare()方法,定义了排序规则,两个方法类似注意区分。引入comparator对象可以使用匿名内部类的方法,会更简洁。
代码:

TreeSet<Student> ts2=new TreeSet<Student>(new Comparator<Student>() {

		@Override
		public int compare(Student stu1, Student stu2) {
			// TODO Auto-generated method stub
			int figture1=Integer.parseInt(stu1.getSid().substring(1));              
			int figture2=Integer.parseInt(stu2.getSid().substring(1));
			int sum=figture1-figture2;
			int s=sum==0? stu1.compareTo(stu2) : sum;                  
			return s;                 
		}
		
	});              //完整语句要有;不然会出错

. . .

相关推荐

额外说明

为什么数据库事务如此重要?

《SQL 从入门到精通》专栏目录 第 01 篇 和数据打交道的你,一定要学会 SQL 第 02 篇 在 SQL 的世界里一切都是关系 第 03 篇 使用 SELECT 语句初步探索数据库 第 04 篇 通过查询条件实现数据过滤 第 05 篇 如何使用 S

额外说明

APICloud(四):图片上传-Java版

这一篇讲“将选择的图片上传到指定的服务器”。 说实话,这个功能写了好久,一会儿json拼的有问题访问不到后台,一会儿后台又说form表单的enctype不是multipart/form-data类型,各种乱七八糟的问题折腾了一下午都没好,第二天再弄的时候

额外说明

解决 : ReferenceError: PubSub is not defined

文章目录 一. 第一步 二.第二步 一. 第一步 npm install --save pubsub-js 二.第二步

额外说明

springboot 整合缓存 : -> Redis(Aop技术融合) 自动

目录 第一步: 先看三层 第二步:使用redis的缓存操作 -> 2.1.1 手动写入redis 缓存操作 ->2.1.2 手动redis缓存的测试 -> 2.1.3 知识点1 @Resource与@Autowired区别 ---> 1. @Autowi

额外说明

【Python】有C#基础怎么学习Python

推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一、前言 本人是已经有了一定的C#基础,所以学起Python来比较容易,但是也容易弄混,所以就想将python的一些语法跟C#进行

额外说明

win7中将窗口拉到屏幕边界,窗口自动在竖直方向上平铺的现象

        在实际测试过程中发现,在某个win7系统中,当我们将非最大化的窗口拉到屏幕边界,窗口会自动在竖直方向上平铺到整个屏幕(窗口宽度不变,高度达到屏幕高度),当我们双击标题栏后,则会恢复到之前的正常态大小。但是在其他win7系统中则没有类似的表

额外说明

【Java 进阶篇】Java Web 编写注册页面案例

当涉及到创建一个Java Web注册页面时,你将需要涵盖很多不同的主题,包括HTML、CSS、Java Servlet和数据库连接。在这篇文章中,我们将详细介绍每个步骤,以帮助你创建一个完整的注册页面。 1. 介绍 注册页面是许多Web应用程序的关键组成

额外说明

《天天数学》连载55:二月二十四日

2月24日 XXIV 数学格言 一个名副其实的科学家,尤其是数学家,跟艺术家一样,在工作中体验到同样的印象;享受到同样性质、同样伟大的乐趣。——亨利·庞加莱(Henri Poincaré) 数学习题 这是星期一,汤姆和杰里做同样的工作。当汤姆该回家的时候

额外说明

大数据学习笔记04:单机模式使用ZooKeeper

文章目录 一、ZooKeeper概述 二、下载ZooKeeper 三、下载JDK8u231 四、由CentOS7克隆一个虚拟机 五、配置虚拟机 1、配置静态IP地址 2、修改主机名 3、修改主机IP映射 六、利用SecureCRT登录虚拟机 1、登录虚拟

ads via 小工具