概述
1 Comparable接口
如果需要对一个对象数组进行排序,Java
提供了两种比较实现的方式,其中之一是:对象所属的类必须实现Comparable
接口。下面是Comparable
接口的代码:
public interface Comparable<T> {
public int compareTo(T o);
}
任何实现Comparable
接口的类都需要包含comoaraTo
方法。即用当前对象与o
作比较,如果这个对象小于o
则返回一个负整数;如果相等则返回0
;否则返回正整数。下面看一个实现Comparable
接口进行排序的实例:
import java.util.Arrays;
public class TestComparable {
public static void main(String[] args) {
Stu[] stus = new Stu[]{new Stu("HC", 25, "CS"), new Stu("HC", 24, "CS"), new Stu("DSC", 24, "CS"), new Stu("MXD", 24, "DQ")};
for (Stu s : stus) {
System.out.println(s);
}
Arrays.sort(stus);
for (Stu s : stus) {
System.out.println(s);
}
}
}
class Stu implements Comparable<Stu> {
private String name;
private int age;
private String dept;
public Stu(String name, int age, String dept) {
this.name = name;
this.age = age;
this.dept = dept;
}
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 String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Stu{" +
"name='" + name + ''' +
", age=" + age +
", dept='" + dept + ''' +
'}';
}
@Override
public int compareTo(Stu o) {
if (!o.getDept().equals(this.dept))
return o.getDept().compareTo(this.dept);
else if (!o.getName().equals(this.name))
return o.getName().compareTo(this.name);
else
return o.getAge() - this.age;
}
}
2 Comparator接口
在上面对Stu
类进行排序的过程中,Stu
类实现了Comparable
接口,并完成了比较规则的定义,但是这种规则写的太死,如果需要对Stu
类进行另一种排序,需要修改Stu
类的源代码。这个时候可以使用Java
提供的第二种比较实现方法:实现Comparator
接口创建一个比较器,利用public static <T> void sort(List<T> list,Comparator<? super T> )
进行比较。
2.1 自定义比较类实现Comparator接口
下面看一个使用Comparator
接口进行排序的例子:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestComparator {
public static void main(String[] args) {
List<Per> pers = new ArrayList<>();
pers.add(new Per("HC", 25));
pers.add(new Per("HC", 23));
pers.add(new Per("HC", 21));
pers.add(new Per("AC", 26));
Collections.sort(pers, new Comp());
for (Per p : pers) {
System.out.println(p);
}
}
}
class Per {
private String name;
private int age;
public Per(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Per{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
class Comp implements Comparator<Per> {
@Override
public int compare(Per o1, Per o2) {
if (!o1.getName().equals(o2.getName()))
return o1.getName().compareTo(o2.getName());
else
return o1.getAge() - o2.getAge();
}
}
2.2 lambda表达式在Comparator接口中的使用
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestComparator {
public static void main(String[] args) {
List<Per> pers = new ArrayList<>();
pers.add(new Per("HC", 25));
pers.add(new Per("HC", 23));
pers.add(new Per("HC", 21));
pers.add(new Per("AC", 26));
Collections.sort(pers, Comparator.comparing(Per::getName).thenComparing(Per::getAge));
for (Per p : pers) {
System.out.println(p);
}
}
}
class Per {
private String name;
private int age;
public Per(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Per{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
上述提到了Comparator接口中的几个静态方法:
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
对需要比较的对象应用上述函数,然后返回的键进行比较。
2.3 匿名内部类排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TestComparator {
public static void main(String[] args) {
List<Per> pers = new ArrayList<>();
pers.add(new Per("HC", 25));
pers.add(new Per("HC", 23));
pers.add(new Per("HC", 21));
pers.add(new Per("AC", 26));
Collections.sort(pers, new Comparator<Per>() {
@Override
public int compare(Per o1, Per o2) {
return o1.getAge() - o2.getAge();
}
});
for (Per p : pers) {
System.out.println(p);
}
}
}
class Per {
private String name;
private int age;
public Per(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Per{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
3 Comparable和Comparator两个接口的区别
Comparable
:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo
方法被称为它的自然比较方法。只能在类中实现compareTo()
一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)
进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。Comparator
强行对某个对象进行整体排序。可以将Comparator
传递给sort
方法(如Collections.sort或Arrays.sort)
,从而允许在排序顺序上实现精确控制。还可以使用Comparator
来控制某些数据结构(如有序set
或有序映射)的顺序,或者为那些没有自然顺序的对象collection
提供排序。
最后
以上就是机智大侠为你收集整理的Comparable和Comparator接口1 Comparable接口2 Comparator接口3 Comparable和Comparator两个接口的区别的全部内容,希望文章能够帮你解决Comparable和Comparator接口1 Comparable接口2 Comparator接口3 Comparable和Comparator两个接口的区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复