Java 几种常见的比较器实现
Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
通常对象之间的比较可以从两个方面去看:
第一个方面:对象的地址是否一样,是否引用自同一个对象。这种方式可以直接使用“==“来完成。
第二个方面:以对象的某一个属性的角度去比较,例如以对象的年龄、出生年月、成绩分数、姓氏字母等。
从最新的JDK8而言,有三种实现对象比较的方法:
一、覆写Object类的equals()方法,即直接写在类里面;
二、继承Comparable接口,并实现compareTo()方法;
三、定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。
由于使用的排序方式的不同,具体选择哪种方法来实现对象的比较也会有所不同。
方式1: 覆写equals()方法
覆写equals()方法,一般用于自己实现对象数组排序的情况,而对于要使用java内置的排序算法时,使用后面两种方式都是可行的。
方式2: 继承Comparable接口,并实现 compareTo()方法
这种方式就是让自己编写的类继承Comparable接口,并实现compareTo()方法,这种情况下,在使用java.util.Arrays.sort() 方法时,不用指定具体的比较器,sort()方法会使用对象自己的比较函数来完成对象的排序。
方式3:继承自Comparator接口,实现compare()方法
一般使用以上两种方法就能够满足实际的开发问题,但是当出现以下情况时,就需要用到Comparator接口:要在已经开发好的代码的基础上完善对象的比较功能时,又不想更改之前的代码,这种情况下,从JDK1.8之后出现了Comparator接口,是对这种情况的一个弥补。
这种情况下,需要单独定义一个对象比较器,继承Comparator接口,并实现compare()方法。
以上三种实现方式的示例代码如下:
package com.mymaven.javademo; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * @since 2017.03.31 * @author mimvp * */ class Student { private String name; private double score; public Student(String name, double score) { this.name = name; this.score = score; } public String getName() { return this.name; } public double getScore() { return this.score; } @Override public String toString(){ return "Student : name: " + this.name + "; score: " + this.score; } // 方式1: 覆写equals()方法 public int equals(Student s) { int result = this.score > s.getScore() ? 1 : (this.score < s.getScore() ? -1 : 0); if(0 == result) { result = this.name.charAt(0) >= s.getName().charAt(0) ? 1 : -1; } return result; } } /** * 方式2: 继承Comparable接口,并实现 compareTo()方法 */ @SuppressWarnings("rawtypes") class Teacher implements Comparable { private String name; private double score; public Teacher(String name, double score) { this.name = name; this.score = score; } public String getName() { return this.name; } public double getScore() { return this.score; } @Override public String toString() { return "Teacher : name: " + this.name + "; score: " + this.score; } public int compareTo(Object obj) { Teacher t = (Teacher) obj; int result = this.score > t.score ? 1 : (this.score < t.score ? -1 : 0); if(result == 0) { result = this.name.indexOf(0) > t.name.indexOf(0) ? 1 : -1; } return result; } } /** * 方式3: 继承自Comparator接口,实现compare()方法 */ class StudentComparator implements Comparator<Student> { public int compare(Student s1, Student s2) { int result = s1.getScore() > s2.getScore() ? 1 : (s1.getScore() < s2.getScore() ? -1 : 0); if(0 == result) { result = s1.getName().indexOf(0) > s2.getName().indexOf(0) ? 1 : -1; } return result; } } /** * 主函数 */ public class JavaDemo { @SuppressWarnings("unchecked") public static void main(String[] args ) { System.out.println("hello world"); // 方式1 Student s1 = new Student("zzz", 80); Student s2 = new Student("bbb", 80); System.out.println(s1.getName() + " >= " + s2.getName() + " : " + s1.equals(s2)); // 方式2 List<Teacher> teachers = new ArrayList<Teacher>(10); teachers.add(new Teacher("ddd", 60)); teachers.add(new Teacher("aaa", 60)); teachers.add(new Teacher("bbb", 80)); teachers.add(new Teacher("ccc", 70)); Collections.sort(teachers); System.out.println(teachers); // 方式3 Student[] students = new Student[] { new Student("ddd", 60), new Student("aaa", 60), new Student("bbb", 80), new Student("ccc", 70), }; Arrays.sort(students, new StudentComparator()); System.out.println(Arrays.deepToString(students)); } }
运行结果:
hello world zzz >= bbb : 1 [Teacher : name: aaa; score: 60.0, Teacher : name: ddd; score: 60.0, Teacher : name: ccc; score: 70.0, Teacher : name: bbb; score: 80.0] [Student : name: aaa; score: 60.0, Student : name: ddd; score: 60.0, Student : name: ccc; score: 70.0, Student : name: bbb; score: 80.0]
1. Comparator 和 Comparable 相同的地方
他们都是java的一个接口, 并且是用来对自定义的class类对象的比较大小,什么是自定义class:
如 public class Person{ String name; int age }
当我们有这么一个personList,里面包含了person1, person2, persion3....., 我们用Collections.sort( personList ), 是得不到预期的结果的. 这时肯定有人要问, 那为什么可以排序一个字符串list呢:
如 StringList{"hello1" , "hello3" , "hello2"}, Collections.sort( stringList ) 能够得到正确的排序, 那是因为
String 这个对象已经帮我们实现了 Comparable接口 , 所以我们的 Person 如果想排序, 也要实现一个比较器。
2. Comparator 和 Comparable 的区别
Comparable
Comparable 定义在 Person类的内部:
public class Persion implements Comparable {..比较Person的大小..}
因为已经实现了比较器,那么我们的Person现在是一个可以比较大小的对象了,它的比较功能和String完全一样,可以随时随地的拿来
比较大小,因为Person现在自身就是有大小之分的。Collections.sort(personList)可以得到正确的结果。
Comparator
Comparator 是定义在Person的外部的, 此时我们的Person类的结构不需要有任何变化,如
public class Person{ String name; int age },
然后我们另外定义一个比较器:
public PersonComparator implements Comparator() {..比较Person的大小..}
在PersonComparator里面实现了怎么比较两个Person的大小. 所以,用这种方法,当我们要对一个 personList进行排序的时候,
我们除了了要传递personList过去, 还需要把PersonComparator传递过去,因为怎么比较Person的大小是在PersonComparator里面实现的, 如:
Collections.sort( personList , new PersonComparator() )
参考推荐:
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2017-04-17 03:35:51
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!
转载注明: Java 几种常见的比较器实现 (米扑博客)