本文主要是介绍Day28 内置比较器(Comparable)与外置比较器(Comparator),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Day28 内置比较器(Comparable)与外置比较器(Comparator)
一、内置比较器——Comparable
1、概念: Comparable
是Java中的一个接口,用于实现对象自然排序的比较器。实现Comparable
接口的类可以定义自己的比较规则,从而使对象在集合中进行排序时按照指定的顺序进行排序。
2、使用方法:
-
实现Comparable接口:
- 实现类需要重写
compareTo()
方法,定义对象之间的比较规则。
public class MyClass implements Comparable<MyClass> {private int value;public int compareTo(MyClass other) {return this.value - other.value;} }
- 实现类需要重写
-
排序对象数组或集合:
- 对实现了
Comparable
接口的对象数组或集合进行排序。
MyClass[] array = new MyClass[]{obj1, obj2, obj3}; Arrays.sort(array);
- 对实现了
-
自定义比较规则:
- 根据实际需求自定义比较规则,可以按照数字大小、字符串顺序等进行比较。
public int compareTo(MyClass other) {// 按照字符串长度比较return this.name.length() - other.name.length(); }
3、举例;
需求:创建学生类,将学生类的对象添加到TreeSet中
import java.util.TreeSet;public class Test03 {/*** 知识点:研究内置比较器的使用 -- Comparable* * 需求:创建学生类,将学生类的对象添加到TreeSet中*/public static void main(String[] args) {TreeSet<Student> set = new TreeSet<>();set.add(new Student("小希", '女', 27, "2401", "001")); set.add(new Student("小空", '女', 23, "2401", "002")); set.add(new Student("小丽", '女', 21, "2401", "003")); set.add(new Student("小光", '女', 31, "2401", "004")); set.add(new Student("小玲", '女', 36, "2401", "005")); set.add(new Student("小步", '女', 29, "2401", "006")); set.add(new Student("小奈", '女', 32, "2401", "007")); set.add(new Student("小阳", '女', 31, "2401", "008")); set.add(new Student("小织", '女', 27, "2401", "009")); set.add(new Student("小伟", '男', 21, "2401", "010")); set.add(new Student("小乐", '男', 20, "2401", "011")); set.add(new Student("小衣", '女', 34, "2402", "001")); set.add(new Student("小莉", '女', 23, "2402", "002")); set.add(new Student("小亚", '女', 21, "2402", "003")); set.add(new Student("小惠", '女', 31, "2402", "004")); set.add(new Student("小香", '女', 27, "2402", "005")); set.add(new Student("铃原", '女', 23, "2402", "006")); set.add(new Student("明日", '女', 28, "2402", "007")); set.add(new Student("小京", '女', 34, "2402", "008")); set.add(new Student("小伟", '男', 18, "2402", "009")); set.add(new Student("小杰", '男', 20, "2402", "010")); for (Student stu : set) {System.out.println(stu);}}
}
public class Student implements Comparable<Student>{private String name;private char sex;private int age;private String classId;private String id;public Student() {}public Student(String classId, String id) {this.classId = classId;this.id = id;}public Student(String name, char sex, int age, String classId, String id) {this.name = name;this.sex = sex;this.age = age;this.classId = classId;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassId() {return classId;}public void setClassId(String classId) {this.classId = classId;}public String getId() {return id;}public void setId(String id) {this.id = id;}//判断两个学生是否相同//比较规则:班级号+学号@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj instanceof Student){Student stu = (Student) obj;if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){return true;}}return false;}@Overridepublic String toString() {return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;}//排序规则:按照年龄排序@Overridepublic int compareTo(Student o) {//this表示添加到TreeSet中的学生对象//o表示TreeSet中的学生对象return this.age - o.age;}
}
二、外置比较器——Comparator
1、概念: Comparator
是Java中的一个接口,用于实现对象的定制排序比较器。与Comparable
接口不同的是,Comparator
接口允许在不修改对象本身的情况下,定义多种不同的排序规则。
2、理解:
通过实现Comparator
接口,可以灵活地定义多种不同的比较规则,适用于需要根据不同条件进行排序的情况。在使用Comparator
接口时,需要注意实现compare()
方法时的返回值含义,通常返回负数表示第一个对象小于第二个对象,返回正数表示第一个对象大于第二个对象,返回0表示两个对象相等。
3、使用方法:
-
实现Comparator接口:
- 实现类需要重写
compare()
方法,定义对象之间的比较规则。
public class MyComparator implements Comparator<MyClass> {public int compare(MyClass obj1, MyClass obj2) {return obj1.getValue() - obj2.getValue();} }
- 实现类需要重写
-
使用Comparator进行排序:
- 在排序时传入自定义的Comparator对象。
List<MyClass> list = new ArrayList<>(); list.add(obj1); list.add(obj2); Collections.sort(list, new MyComparator());
-
自定义比较规则:
- 根据实际需求自定义比较规则,可以按照数字大小、字符串顺序等进行比较。
public int compare(MyClass obj1, MyClass obj2) {// 按照字符串长度比较return obj1.getName().length() - obj2.getName().length(); }
4、举例:
需求:将学生类的对象添加到TreeSet中
场景 - 联合开发:
1.Student类是小伟开发的
2.何老师要把Student类的对象添加到TreeSet中,但是Student的排序规则不满足何老师的需求
3.何老师想的是按照名字长度排序,长度一致按照年龄排序
import java.util.Comparator;
import java.util.TreeSet;public class Test04 {/*** 知识点:研究外置比较器的使用 -- Comparator* * 需求:将学生类的对象添加到TreeSet中* 场景 - 联合开发:* 1.Student类是巴得伟开发的* 2.何老师要把Student类的对象添加到TreeSet中,但是Student的排序规则不满足何老师的需求* 3.何老师想的是按照名字长度排序,长度一致按照年龄排序* * 比较器的优先级别:外置比较器 > 内置比较器*/public static void main(String[] args) {//扩展:new Comparator 匿名内部类的使用场景!!!TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {if(o1.equals(o2)){return 0;}int nameLen1 = o1.getName().length();int nameLen2 = o2.getName().length();if(nameLen1 != nameLen2){//return nameLen1 - nameLen2;return Integer.compare(nameLen1, nameLen2);}int age1 = o1.getAge();int age2 = o2.getAge();if(age1 != age2){return Integer.compare(age1, age2);}return 1;}});set.add(new Student("小希", '女', 27, "2401", "001")); set.add(new Student("小空", '女', 23, "2401", "002")); set.add(new Student("小丽", '女', 21, "2401", "003")); set.add(new Student("小光", '女', 31, "2401", "004")); set.add(new Student("小玲", '女', 36, "2401", "005")); set.add(new Student("小步", '女', 29, "2401", "006")); set.add(new Student("小奈", '女', 32, "2401", "007")); set.add(new Student("小阳", '女', 31, "2401", "008")); set.add(new Student("小织", '女', 27, "2401", "009")); set.add(new Student("小伟", '男', 21, "2401", "010")); set.add(new Student("小乐", '男', 20, "2401", "011")); set.add(new Student("小衣", '女', 34, "2402", "001")); set.add(new Student("小莉", '女', 23, "2402", "002")); set.add(new Student("小亚", '女', 21, "2402", "003")); set.add(new Student("小惠", '女', 31, "2402", "004")); set.add(new Student("小香", '女', 27, "2402", "005")); set.add(new Student("铃原", '女', 23, "2402", "006")); set.add(new Student("明日", '女', 28, "2402", "007")); set.add(new Student("小京", '女', 34, "2402", "008")); set.add(new Student("小伟", '男', 18, "2402", "009")); set.add(new Student("小杰", '男', 20, "2402", "010")); for (Student stu : set) {System.out.println(stu);}}
}
ublic class Student implements Comparable<Student>{private String name;private char sex;private int age;private String classId;private String id;public Student() {}public Student(String classId, String id) {this.classId = classId;this.id = id;}public Student(String name, char sex, int age, String classId, String id) {this.name = name;this.sex = sex;this.age = age;this.classId = classId;this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getClassId() {return classId;}public void setClassId(String classId) {this.classId = classId;}public String getId() {return id;}public void setId(String id) {this.id = id;}//判断两个学生是否相同//比较规则:班级号+学号@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj instanceof Student){Student stu = (Student) obj;if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){return true;}}return false;}@Overridepublic String toString() {return name + "\t" + sex + "\t" + age + "\t" + classId + "\t" + id;}//排序规则:按照年龄排序@Overridepublic int compareTo(Student o) {//this表示添加到TreeSet中的学生对象//o表示TreeSet中的学生对象return this.age - o.age;}
}
三、内置比较器(Comparable)与外置比较器(Comparator)的区别
-
Comparable接口:
- 作用:用于实现对象的自然排序,即对象本身就具有比较能力。
- 实现方式:对象类实现Comparable接口,重写compareTo()方法定义比较规则。
- 排序方式:对象在集合中进行排序时,会按照实现Comparable接口的类的compareTo()方法定义的规则进行排序。
- 局限性:一个类只能实现Comparable接口一次,无法同时支持多种排序规则。
-
Comparator接口:
- 作用:用于实现对象的定制排序,可以定义多种不同的排序规则。
- 实现方式:单独编写比较器类实现Comparator接口,重写compare()方法定义比较规则。
- 排序方式:在排序时,通过传入Comparator对象来指定使用哪种比较规则进行排序。
- 灵活性:允许在不修改对象本身的情况下定义多种排序规则,适用于需要根据不同条件进行排序的情况。
-
使用场景:
- Comparable:适用于对象自身就具有固定的比较规则,如基于某个属性的自然排序。
- Comparator:适用于需要根据不同条件进行排序,或者对第三方类进行排序时无法修改源代码的情况。
-
排序优先级:
- 当对象实现了Comparable接口时,在使用Collections.sort()等方法进行排序时,会优先使用对象自身的compareTo()方法定义的比较规则。
- 如果需要使用外置比较器的规则进行排序,则需要显式传入Comparator对象。
理解: 总的来说,Comparable接口适用于对象自身具有固定的比较规则的情况,而Comparator接口适用于需要灵活定义多种排序规则的情况。根据具体需求选择合适的比较器方式可以实现灵活、高效的对象排序。
这篇关于Day28 内置比较器(Comparable)与外置比较器(Comparator)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!