自定义类型,对象的比较

如果我们自定义一个学生类,并实现了两个对象,类中成员属性有姓名,年龄,我们该如何比较呢,先看下面这段代码,自定义了一个学生类

package main;

public class Student {
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

然后我们在,main方法中实例化并初始化两个对象

package main;

public class Main {
    public static void main(String[] args) {
        Student s=new Student("wangcai",11);
        Student s1=new Student("cuihua",13);
    }
}

此时,我们想比较这两个对象,就得使用到java内置的comparable接口,<>括号中放入要比较的类

package main;
//实现comparable接口
public class Student implements Comparable<Student>{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据年龄比较大小的
    @Override
    public int compareTo(Student o) {
       if (this.age<o.age){
           return -1;
       }
       else if (this.age>o.age){
           return 1;
       }
       else{
           return 0;
       }

    }
}

在main方法中,我们这样子写

package main;

public class Main {
    public static void main(String[] args) {
        Student s=new Student("wangcai",11);
        Student s1=new Student("cuihua",13);
        System.out.println(s.compareTo(s1));
    }
}

,通过运行之后的结果来看,打印了-1,所以这个通过年龄比较两个大小算是成功了。


那么,又如何通过姓名name来比较呢,和通过年龄比较大小有所不同

我们通过改造一下compareTo方法来实现,以下代码改造后的

package main;
//实现comparable接口
public class Student implements Comparable<Student>{
    public String name;
    public int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据name比较大小的
    @Override
    public int compareTo(Student o) {
      return this.name.compareTo(o.name);
    }
}

,此时,在main方法中,我们就可以通过name来比较对象大小了。不过,我们需要注意几个点:

1.在比较name时,是从字符串的第一个字符开

始比较,如果,s的第一个字符s1第一个字符大,便是s大。输出的是之间ASCII码值的差值。否则,以此往后推,如果全部一样,输出的就是0。

2.这个东西有缺陷,重写方法中比较方式一般用于固定的比较。不适合非常灵活的比较


                                                                给对象数组排序

class Student {
  private String name;
  private int age;
  public Student(String name, int age) {
    this.name = name;
    this.age = age;
 }
 
  @Override

  public String toString() {
    return "[" + this.name + ":" + this.age + "]";
 }
}

再给定一个学生对象数组, 对这个对象数组中的元素进行排序(按年龄降序).

Student[] students = new Student[] {
  new Student("zhangsan", 20),
  new Student("lisi", 26),
  new Student("wangwu", 27),
  new Student("zhaoliu", 22),
};

按照我们之前的理解, 数组我们有一个现成的 sort 方法, 能否直接使用这个方法呢?

Arrays.sort(students);
System.out.println(Arrays.toString(students));
// 运行出错, 抛出异常.
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable

仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定? 需要我们额外指定.

//在student类重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据年龄大小进行排序的
@Override
public int compareTo(Student o) {
  return this.name.compareTo(o.name);
}

这样之后,我们便可以根据年龄大小来对这个对象数组进行排序。那么,是否还有别的方法呢?

我们又引出了comparator接口

package main;

import java.util.Comparator;
//这里重新定义了一个Agecomparator类,根据年龄进行排序

public class Agecomparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.age- o2.age;
    }
}

main方法中

package main;

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Student[] students=new Student[]{
                new Student("zhangsan", 20),
                new Student("lisi", 26),
                new Student("wangwu", 27),
                new Student("zhaoliu", 22),
        };
            Agecomparator agecomparator=new Agecomparator();
//这里直接将数组名和比较方式丢进去,就可以对对象数组排序了
            Arrays.sort(students,agecomparator);
            String str=Arrays.toString(students);
        System.out.println(str);

    }
}

[Student{name='zhangsan', age=20}, Student{name='zhaoliu', age=22}, Student{name='lisi', age=26}, Student{name='wangwu', age=27}]

以上就是输出排序后。同理,我们只需要将重写的compare方法改一下,就可以根据name来给对象数组排序。

package main;

import java.util.Comparator;


public class Agecomparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.name.compareTo(o2.name);
    }
}

以上,大概就是本节内容。总结一下,我们利用了comparable接口来比较两个对象的大小,根据重写的方法不同来比较不同的属性。对对象数组进行排序,就可以里利用comparator接口了,这里是重新创建了一个类来实现这个接口,并在Array.sort方法中将数组名和比较方式传入

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值