Java思考——如何使用Comparable按照我们指定的规则排序?
练习:
存储学生对象并遍历,创建TreeSet集合使用无参构造方法,并按照年龄从小到大的顺序排序,若年龄相同再按照姓名的字母顺序排序
分析:
1.创建学生类,成员变量name,age;无参构造,带参构造;get\set方法;
2.创建测试类,添加数据并进行排序;直接排序会报错
3.需要Student实现comparable接口并重写Comparable中的compareto方法来实现按照我们给定的顺序排序
Student类代码
public class Student{
//成员变量
private String name;
private int age;
//构造方法
public Student(){}
public Student(String name,int age){
this.age=age;
this.name=name;
}
//get\set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试类
public class StudentDemo {
public static void main(String[] args) {
//创建TreeSet对象
TreeSet<Student>ts=new TreeSet<Student>();
//创建学生对象
Student s=new Student("张三",18);
Student s1=new Student("张四",17);
Student s2=new Student("张五",19);
Student s3=new Student("张六",12);
//添加数据
ts.add(s);
ts.add(s1);
ts.add(s2);
ts.add(s3);
//遍历
for (Student ss:ts){
System.out.println(ss.getName()+ss.getAge());
}
}
}
第一次运行结果提示Student cannot be cast to java.lang.Comparable,这个时候我们就需要在Student类实现comparable接口重写compareto方法,并给定返回值
public class Student implements Comparable<Student>{
//成员变量
private String name;
private int age;
//构造方法
public Student(){}
public Student(String name,int age){
this.age=age;
this.name=name;
}
//get\set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Student o) {
// return 0;
// return 1;
// return-1;
}
}
那么可以看到compareto方法中有三个返回值分别是0、1、-1三种情况;
1.return 0:返回值是0的情况下再遍历集合只会在控制台打印出第一个元素;这是因为存入第一个元素时不需要比较直接存入集合,第二个 元素再存入是就需要跟第一个元素比较,但返回值为0,就会认为第二个元素跟第一个元素是相同的、重复的,就不存储,依此类推
2.return 1:返回值是1的情况下再遍历集合会按照存储数据的顺序在控制台全部打印出来;同样的,第一个元素存入不比较,第二个元素与第一个元素比较,返回值为1;就会认为第二个元素比第一个元素大,排在第一个元素后面,以此类推
3.return -1:与renturn 1的情况相反,也就是会按照存储数据顺序的倒序方式在控制台打印出来
思考:我们需要按照年龄的大小排序,这本质上不是只要返回值是一个正数就行了嘛,那我们就可以在compareto方法中这样写
public int compareTo(Student s) {
//return 0;
//return 1;
int num=this.age-s.age;
return num;
}
其中,this是方法内部就有的,在这里this.age代表当第一个元素存储后的后续每一个元素的年龄,我们用后续存储的元素年龄减去第一个元素的年龄当结果是-1时,就将该元素排在第一个元素前面,为1时,就排在后面,为0时就代表重复不存储
但是在我们完成按照年龄进行排序后有出现一个问题:当两个元素姓名不同年龄相同时,再按照我们设定的规则就不会将年龄相同的最后一个元素存储进去,因为它们两个年龄相减为0,默认重复了。所以在年龄相同的情况下,我们还要再比较姓名,如下
public int compareTo(Student s) {
//return 0;
//return 1;
int num=this.age-s.age;
int num1=num==0?this.name.compareTo(s.name):num;
return num1;
}
当年龄不同时返回的还是之前num的值,当年龄相同时比较姓名是否相同不相同返回1代表可以进行存储,相同返回0代表重复。
在这里因为string 本身就实现了comparable接口,所以可以直接调用compareto方法,这样就很好的解决了问题又保证了数据的唯一性
总结:
1.TreeSet集合存储自定义对象时,无参构造方法使用的是自然排序也就是按照存储元素的顺序进行排序
2.自然排序也就是让元素所属的类实现Comparable接口,重写compareto(T o)方法
3.重写compareto(T o)方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
Java思考——如何使用Comparable按照我们指定的规则排序?的更多相关文章
- java的Comparator和Comparable
java的Comparator和Comparable 当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. ...
- 1.java中Comparor与Comparable的问题
1.Comparator中compare()与Comparable中compareTo()方法的区别 Treeset集合创建对象后, A:如果是空构造,即TreeSet<Student> ...
- java源码之Comparable和Comparator
1,Comparable 简介 Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着“该类支持排序”. 即然实现Comparable接口的类支持排序,假设现在存在“实 ...
- java.io.FileNotFoundException(系统找不到指定的路径。)
报错:java.io.FileNotFoundException(系统找不到指定的路径.) 解决方法: 1.检查文件路径是否正确 2.另外,使用OutputStream时,如果文件不存在,会自动创建文 ...
- java学习--自定义类的实例的大小比较和排序
我们知道Object类有一个equals方法,用于比较两个对象是否相等 我们只要在自定义类中重写了equals方法(若不重写就是比较两个实例的地址,相当于==)就可以用来比较该类的两个实例是否相等 问 ...
- 对JavaScript对象数组按指定属性和排序方向进行排序
引子 在以数据为中心的信息系统中,以表格形式展示数据是在常见不过的方式了.对数据进行排序是必不可少的功能.排序可以分为按单个字段排序和按多个字段不同排序方向排序.单字段排序局限性较大,不能满足用户对数 ...
- 组件注册-自定义TypeFilter指定过滤规则
组件注册-自定义TypeFilter指定过滤规则 4.1 FilterType.ANNOTATION 按照注解方式 4.2 FilterType.ASSIGNABLE_TYPE 按照给定的类型 @Co ...
- 4、组件注册-自定义TypeFilter指定过滤规则
4.组件注册-自定义TypeFilter指定过滤规则 4.1 FilterType.ANNOTATION 按照注解方式 4.2 FilterType.ASSIGNABLE_TYPE 按照给定的类型 @ ...
- sort如何按指定的列排序·百家电脑学院
sort如何按指定的列排序·百家电脑学院 sort如何按指定的(9php.com)列排序 0000 27189 41925425065f ...
随机推荐
- ASP.NET Core 6框架揭秘实例演示[07]:文件系统
ASP.NET Core应用具有很多读取文件的场景,如读取配置文件.静态Web资源文件(如CSS.JavaScript和图片文件等).MVC应用的视图文件,以及直接编译到程序集中的内嵌资源文件.这些文 ...
- MyBatisPlus分页不起作用?因为少了配置
/** @author QiuQiu&LL @create 2021-09-05 0:25 @Description: / @EnableTransactionManagement @Conf ...
- JSP中引入JQuery和Layer,浏览器控制台报错404
路径没有写错,文件也存在为什么会报404呢?,解决方法是将layer文件夹使用source的方式 解决办法: 这时候你会发现layer文件夹变成了蓝色,重启一次服务器,页面中就没有报404异常了 总结 ...
- HDFS免重启挂载新磁盘
背景 在生产环境中,集群节点磁盘大小不同,其使用率也会不同,HDFS虽有均衡策略,但也会有数据不平衡的情况,有些节点磁盘就会被打满,然后这个节点就不健康了(Unhealthy Nodes),Yarn的 ...
- 分布式缓存NCache使用
NCache作为缓存优点币Redis有优势,但是收费的所以选用的不多吧.下面简单实操一下: 首先官网下载组件NCache Download Center (alachisoft.com),这里选择企业 ...
- IDEA如何快速生成get和set方法
方法一:1.鼠标右击"Generate"2.点击"Getter and Setter",3.将定义的字段全部选中,点击OK.方法二:使用alt+insert 快 ...
- Vulhub-漏洞环境的搭建(详细版)
安装Vulhub需要的基础环境 更新现有的软件 复制代码 1 2 sudo apt-get update sudo apt-get upgrade 安装Docker 复制代码 1 2 3 4 5 6 ...
- 一文带你盘点市场上主流的BI产品主要有哪些
随着时代的发展,商业智能使数据分析和数据可视化的门槛不断降低,使得企业各级人员都能进行数据分析,从而加深业务洞察,推动企业发展.而在数据分析领域,BI产品发挥了十分重要的作用. 市场需求变化日益频繁 ...
- 你的程序员女孩「GitHub 热点速览 v.22.09」
本周最火的项目要数上周推荐的开源项目 How to Cook,火到一周涨了 18k+ star,但网友对它的定量烹饪方法褒贬不一.在本人看来,烹饪本就是一门"玄学",萝卜青菜各有所 ...
- linux下通过脚本方式对中间件weblogic进行补丁升级
转至:http://bbs.learnfuture.com/topic/48 linux下通过脚本方式对中间件weblogic进行补丁升级 刘五奎 [摘要] 在运维行业,系统或软件漏洞每每牵动着每一个 ...