当前位置:网站首页>解析treeSet集合进行自定义类的排序
解析treeSet集合进行自定义类的排序
2022-08-04 10:32:00 【SSS4362】
解析treeSet集合进行自定义类的排序
1 底层
1.1 treeSet是对传入的数据进行排序了,排序使用的方法是compareTo方法,add的加入的那个数相当于调用者
Integer里面的compareTo源码如下所示
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
//传入的数据就相当于你之前在集合里面的数据,很显然是String类型的数据,你把一个String类型传给Integer类型的形参,肯定会出现类型转换异常啊
//这个是运行时异常,出现异常时会生成一个异常对象,并抛出,运行时异常在编译期间是无需要进行处理的
1.2 排序要求所传入的数据类型必须相等(泛型去约束),不然就会出现classCastException异常
用到了多态(是用大的范围去接收),你本质是用Integer对象的数据,因此调用的是Integer里面的compareTo方法,因此若你在实参部分传入一个字符串类型,必然是会出现类型转换异常的
1.3 所有源码里面需要比较大小的类都实现了java.lang.Comparable接口
Integer类
String类
2.实现方法
2.1 实现Comparable接口
2.1.1 核心思路
a 自定义类需要实现Comparable接口并且重写compareTo方法
b compareTo方法通过this(调用者)和传入的参数进行合理的逻辑判断
一般是返回this.属性减去传入参数.属性 代表升序,反过来就是降序
如果是小数类型的比较的话,需要单独对>0和<1以及>-1小于0这两个情况进行判断
前一种返回正数(前大于后),后一种返回负数(前小于后),无论升序还是降序都是这样的,只需要去改前面的减法表达式就行
注意:自定义类可以不用实现equals方法也可以比较成功,因为它底层并没有调用equals方法去进行内容的比较,而是把对应的类型进行拆分逐个比较了,但是我们需要重写equals方法是因为可能其他的方法也需要调用它,并不是比较方法需要用到它
它是通过compareTo进行比较添加的,如果比较的那个属性值相等,不能返回0,随便返回-1或者1都行,返回-1代表插入的该数会返回到之前就存在的数字的前面,如果为1就代表插入的数会在相同数字的后面
c 只对一个属性进行排序的示例代码
Student类
package Work03;
import java.util.Objects;
public class Student{
private String name;
private int age;
private float degree;
//分数
public Student() {
}
public Student(String name, int age, float degree) {
this.name = name;
this.age = age;
this.degree = degree;
}
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 float getDegree() {
return degree;
}
public void setDegree(float degree) {
this.degree = degree;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", degree=" + degree +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Float.compare(student.degree, degree) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, degree);
}
}
CompareDegree1类
package Work03;
import java.util.Comparator;
public class CompareDegree1 implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
//按照成绩去进行降序
float temp=o2.getDegree()-o1.getDegree();
//也可以写成>0返回正数,<=0返回负数,=0意味着插入的数字会在之前已经存在过的数据的上方
if (temp==0){
return 1;
}
if(temp>0&&temp<1){
return 1;
}else if(temp>-1&&temp<0){
return -1;
}
return (int)temp;
}
}
TestStudent02类
package Work03;
import java.util.Set;
import java.util.TreeSet;
public class TestStudent02 {
public static void main(String[] args) {
Set<Student> s=new TreeSet(new CompareDegree1());
s.add(new Student("马超",20,88.6f));
s.add(new Student("黄忠",22,77.7f));
s.add(new Student("李典", 20, 77.7f));
s.add(new Student("曹操",22,88.7f));
for (Student temp:s
) {
System.out.println(temp);
}
}
}
d 只对一个属性进行排序的示例代码代码运行截图
2.1.2 示例代码
Student类
package Work03;
import java.util.Objects;
public class Student implements Comparable<Student>{
private String name;
private int age;
private float degree;
//分数
public Student() {
}
public Student(String name, int age, float degree) {
this.name = name;
this.age = age;
this.degree = degree;
}
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 float getDegree() {
return degree;
}
public void setDegree(float degree) {
this.degree = degree;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", degree=" + degree +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Float.compare(student.degree, degree) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, degree);
}
@Override
public int compareTo(Student o) {
//得不到想要的结果,一般是compareTo里面的逻辑判断出了问题
if(this.degree==o.degree){
//如果成绩相同,则需要再根据年龄进行排序
return this.age-o.age;
}else{
//降序需要倒过来,然后里面返回数值的正负和之前没关系
float temp=o.degree-this.degree;
if(temp>0&&temp<1){
return 1;
}
if(temp>-1&&temp<0){
return -1;
}
return (int)temp;
}
}
}
TestStudent02类
package Work03;
import java.util.Set;
import java.util.TreeSet;
public class TestStudent02 {
public static void main(String[] args) {
Set<Student> s=new TreeSet();
s.add(new Student("马超",20,88.6f));
s.add(new Student("黄忠",22,77.7f));
s.add(new Student("李典", 20, 77.7f));
s.add(new Student("曹操",22,88.9f));
for (Student temp:s
) {
System.out.println(temp);
}
}
}
2.1.3 示例代码运行截图
2.2 实现java.util.Comparator接口
2.2.1 核心思路
a 写一个自定义比较类实现java.util.Comparator接口
b 重写该接口里面的compare方法逻辑
c 然后在实例化treeSet对象的时候,丢入一个匿名自定义比较对象(里面含有排序规则)
d. 后面使用迭代器去进行遍历取出并打印里面的值即可
2.2.2 示例代码
Student类
package Work03;
import java.util.Objects;
public class Student{
private String name;
private int age;
private float degree;
//分数
public Student() {
}
public Student(String name, int age, float degree) {
this.name = name;
this.age = age;
this.degree = degree;
}
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 float getDegree() {
return degree;
}
public void setDegree(float degree) {
this.degree = degree;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", degree=" + degree +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Float.compare(student.degree, degree) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, degree);
}
}
CompareDegree类
package Work03;
import java.util.Comparator;
public class CompareDegree implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
if(o1.getDegree()==o2.getDegree()){
//如果成绩一样,需要对年龄进行升序排序
return o1.getAge()-o2.getAge();
}else{
//返回值为int类型,但是可能需要强转,所以需要考虑减出来的结果是的绝对值结果是小数的情况
float temp=o2.getDegree()-o1.getDegree();
if(temp>0&&temp<1){
return 1;
}
if(temp>-1&&temp<0){
return -1;
}
return (int)temp;
}
}
}
TestDegree02类
package Work03;
import java.util.Set;
import java.util.TreeSet;
public class TestStudent02 {
public static void main(String[] args) {
Set<Student> s=new TreeSet(new CompareDegree());
s.add(new Student("马超",20,88.6f));
s.add(new Student("黄忠",22,77.7f));
s.add(new Student("李典", 24, 77.7f));
s.add(new Student("曹操",22,88.9f));
for (Student temp:s
) {
System.out.println(temp);
}
}
}
2.2.3 示例代码运行截图
2.3 用匿名内部类实现java.util.Comparator接口
2.3.1 核心思路
a 使用匿名内部类(这个类没有名字)去实现java.util.Comparator接口,(仅限于该对象去使用)
b.通过foreach循环取出并打印里面的每一个元素
2.3.2 示例代码
Student类
package Work03;
import java.util.Objects;
public class Student{
private String name;
private int age;
private float degree;
//分数
public Student() {
}
public Student(String name, int age, float degree) {
this.name = name;
this.age = age;
this.degree = degree;
}
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 float getDegree() {
return degree;
}
public void setDegree(float degree) {
this.degree = degree;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", degree=" + degree +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Float.compare(student.degree, degree) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, degree);
}
}
TestDegree02类
package Work03;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class TestStudent02 {
public static void main(String[] args) {
Set<Student> s=new TreeSet(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//前面减去后面,升序,后面减去前面是降序,这里来个升序
float temp=o1.getDegree()-o2.getDegree();
if(temp==0){
//如果成绩相等就去比较年龄,按照年龄的升序去进行排列
//前减去后就是升序
return o1.getAge()-o2.getAge();
}
//大于0返回正数,小于0就返回负数,这个规则可以记一下
return temp>0?1:-1;
}
});
s.add(new Student("马超",20,88.6f));
s.add(new Student("黄忠",22,77.7f));
s.add(new Student("李典", 24, 77.7f));
s.add(new Student("曹操",22,88.9f));
for (Student temp:s
) {
System.out.println(temp);
}
}
}
2.3.3 示例代码运行截图
3.总结
3.1 尽量采用2.2这种采用类去实现Comparator接口这种方式。
3.1.1 理由
例如商品类里面有时需要根据价格排序,有时需要对销量进行排序,用另外两种每次都得改大量的代码,而采用类1实现价格排序,类2实现销量排序,new treeSet对象的时候根据需求去放入合适的类,这样无需进行代码的改动
3.2 虽然用非匿名内部类去实现Comparator接口(util包下面的)的方式比较多,但是另外两种也是要会的,
3.2.1 理由
a 方便看懂他人的代码
b 另外会了三种就可以根据实际情况去选择合适的方法,而不是所有情况都用那么一种
边栏推荐
- 在测试集上训练,还能中CVPR?这篇IEEE批判论文是否合理?
- ROI LTV CPA ECPM体系讲解
- HCIP 第十八天
- 解决:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING
- 高级转录组分析和R数据可视化火热报名中(2022.10)
- Win11文件资源管理器找不到选项卡怎么办?
- MySQL core SQL: SQL structured query statements, library, table operation, CRUD
- 小程序容器加快一体化在线政务服务平台建设
- C#/VB.NET:在 Word 中设置文本对齐方式
- 栈与队列的实现
猜你喜欢
【Idea系列】idea配置
超宽带UWB实时精准定位,短距离无缝交互应用,物联网厘米级精度方案
美摄问答室|美映 VS 美摄云剪辑
Win11如何隐藏输入法悬浮窗?
iMeta | Baidu certification is completed, search "iMeta" directly to the publisher's homepage and submission link
什么是终端特权管理
[论文阅读] Unpaired Image-to-Image Translation Using Adversarial Consistency Loss
helm安装
被Win11安全中心误删除的文件怎么恢复?
HTB-Nibbles
随机推荐
iMeta | Baidu certification is completed, search "iMeta" directly to the publisher's homepage and submission link
Win11文件资源管理器找不到选项卡怎么办?
ThreadLocal详细分析
Jina 实例秀|基于神经搜索的网络安全威胁检测(一)
二叉树的基础练习
HTB-Nibbles
Qt:小的任务管理器(task)
Win10电脑经常发出叮咚声音怎么关闭
二叉树与堆
【c】操作符详解(二)
redis解决分布式session问题
OD-Model【5】:YOLOv1
利用pytest hook函数实现自动化测试结果推送企业微信
2022-08-03 第六小组 瞒春 学习笔记
LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三
低代码是开发的未来吗?浅谈低代码开发平台的发展现状及未来趋势
There are 12 balls, including 11 weight, only one, don't know is light or heavy. Three times in balance scales, find out the ball.
CompletableFuture接口核心方法介绍
Win11如何隐藏输入法悬浮窗?
Jina 实例秀|七夕神器!比你更懂你女友的AI口红推荐