一 基本类型比较
Java中,基本类型的对象可以直接比较大小
public class TestCompare {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a > b); //false
System.out.println(a < b); //true
System.out.println(a == b); // false
char c1 = 'A';
char c2 = 'B';
System.out.println(c1 > c2); //false
System.out.println(c1 < c2); //true
System.out.println(c1 == c2);//false
boolean b1 = true;
boolean b2 = false;
System.out.println(b1 == b2); //false
System.out.println(b1 != b2);//true
}
}
二 引用类型的比较
引用数据类型比较大小的时候会报错,原因是因为 > 不能用作比较引用数据类型.
而 ==号出来的结果并不是我们想要的比较结果,因为 == 只能比较用用数据类型的地址 而不是对象本身.
public class TestCompare {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
Student s3 = s2;
//Operator '>' cannot be applied to 'Student'
//System.out.println(s1 > s2);
System.out.println(s1 == s2);// false
System.out.println(s1 == s3);// true
}
}
class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
因此需要重写基类的equals方法这样调用equals方法就可以比较引用数据类型了
对于Java中用户实现自定义类型**,都默认继承Object类,而Object类中提供了equal方法**
而==默认情况下调用equals方法 但是该方法的比较规则是:没有比较引用变量引用对象的内容,而是直接比较引用变量的地址 并不是用户预期的效果
@Override
//重写基类的equals方法
public boolean equals(Object o) {
//如果指向同一个对象 返回true
if (this == o) return true;
//如果对象为null
if (o == null ||
//或者传入对象不是Card类型 返回false
getClass() != o.getClass()) return false;
Student student = (Student) o;
//在基于比较传入对象和本身对象的age 和 name 是否相同
//这里的equals方法是String实现的基类equals方法
return age == student.age && Objects.equals(name, student.name);
}
但是仍然存在缺陷 因为返回值是一个boolean类型 无法比较一个具体的大小 以及 对该类进行排序, 而达到某些预期功能无法实现,因此我们引入比较类接口 Comparable 和 Comparator比较器.
1.Comparable接口类的比较
Student类实现Comparable类接口实现CompareTo()方法
对于该类,只需要实现学生年龄大小比较
class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
}
}
public class Compare {
public static void main(String[] args) {
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",25);
Student s3 = new Student("王五",18);
System.out.println(s1.compareTo(s2));// < 0 说明 s1岁数小于s2
System.out.println(s1.compareTo(s3));// == 0说明岁数一样大
System.out.println(s2.compareTo(s3));// > 0 说明 s2岁数大于s3
}
}
2.Comparator比较器
相对于Comparable比较来说 对于该类的相对入侵较弱,但对算法代码实现侵入性强,可以不改动Student类来实现比较的目的
定义以个年龄比较器只需要拿这个进行比较即可
class AgeComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
//这里使用不了age 因为是私有属性
return o1.getAge() - o2.getAge();
}
}
从而实现用户预期比较功能
package Compare_Code;
import java.util.Comparator;
public class Compare {
public static void main(String[] args) {
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",25);
Student s3 = new Student("王五",18);
AgeComparator ageComparator = new AgeComparator();
System.out.println(ageComparator.compare(s1, s2));// < 0 说明 s1岁数小于s2
System.out.println(ageComparator.compare(s1, s3));// == 0说明岁数一样大
System.out.println(ageComparator.compare(s2, s3));// > 0 说明 s2岁数大于s3
}
}
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class AgeComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
//这里使用不了age 因为是私有属性
return o1.getAge() - o2.getAge();
}
}
对于三种方式的比较
覆写的方法 | 说明 |
Object.equals | 因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与否 |
Comparable.compareTo | 需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序 |
Comparator.compare | 需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强 |