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

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

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

收录于:152天前

对类实现整体排序须使用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;                 
		}
		
	});              //完整语句要有;不然会出错

. . .

相关推荐

额外说明

使用JProfiler分析dump文件定位OOM

下载地址 https://www.ej-technologies.com/download/jprofiler/files 创建测试用例 idea写一个简单springboot+web的测试代码,并且进行jvm配置。 jvm参数配置 -Xms300m -

额外说明

mysql优化限制

  使用id全为排序字段。   或如下优化,10W数据   SELECT * FROM `wx_login` ORDER BY id DESC LIMIT 100500,20;  #0.186 优化后: SELECT a.* FROM wx_login

额外说明

Python:ValueError: No tables found matching pattern ‘.+‘

背景 用pandas的readhtml方法读Selenium拿下来的网页元素时发生报错。 之前这个爬虫已经正常运行了几周,感觉是网页源码出了什么问题。 思考 网上关于这个报错的原因解释千奇百怪,所以觉得是个挺宽泛的报错,原因还是得结合实际情况自己分析。

额外说明

[Eigen中文文档] C++中的template和typename关键字

文档总目录 本文目录 使用 template 和 typename 关键字定义模板 显示 template 关键字的第二次使用的示例 解释 进一步阅读的资源 英文原文(The template and typename keywords in C++)

额外说明

Linux:使用sed命令替换文件内容实操及各种报错问题解决

工作遇到需要在页面一键操作,后端进行自动化运维部署的事情,这里就用的了sed命令,linux的学问真的要花时间好好学习一番了! 上面图片是AI创作生成!如需咒语可私戳哦! 目录 需求背景 sed命令介绍 sed命令实操 查 查-某行的数据 查-连续某几行

额外说明

Linux批量机器查询日志

同一个服务搭建集群,导致线上机器太多,想要查询某次报错日志需要准确定位线上机器才能进行错误排查,一台台机器去搜日志不太可能,最好可以一次性对机器批量查询出来包含我们想查找日志内容的机器,然后再去登录对应机器排查问题 操作命令: pgm -A -f ip.

额外说明

2023.8.18 关于测试用例

目录 测试用例的概念 测试用例总体设计方法  基于需求的设计 等价类 边界值 判定表 场景设计法 错误猜测法 正交表 测试用例的概念 四大要素: 测试环境 测试数据 测试步骤 预期结果 简单例子: 测试用例总体设计方法  基于需求的设计 实例: 注意:

额外说明

ES6中的var,let,const

文章目录 前言 一、var命令和let命令 1.var命令和let命令的声明 2.var命令和let命令的使用区别 二、const命令 总结 前言 讲解var命令,let命令,const命令 一、var命令和let命令 var命令,let命令都是用来声明

额外说明

Java PDF文件生成

需求:根据订单数据生成 PDF 文件 解决方案:想法是通过本地Excel模板和订单数据生成PDF文件。 首先将数据填写到Excel模板中,然后通过Excel将其转换为PDF文件并输出PDF文件。 Excel模板的内容如下: 生成PDF所需的依赖如下:

ads via 小工具