Comparable
Comparable是排序接口,若一个类实现Comparable接口即可支持排序。Comparable定义了一个方法:
public interface Comparable<T> {
public int compareTo(T o);
}
有些标准的Java平台类实现了Comparable接口,例如String类。这个类的compareTo方法依据字典序(有时称为词典序)对字符串进行比较。
如果要插人自定义的对象,就必须通过实现Comparable接口自定义排列顺序。在 Object类中,没有提供任何comparcTo接口的默认实现。
如果一个类实现了Comparable的接口,可以通过调用泛型为该类的集合或数组通过Collection.sort()或Arrays.sort()方法进行排序。
下面是一个示例,展示了如何用Person类的姓名对Person对象排序
package entity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
package entity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Author Lbl
* @Date 2021/12/30 18:50
* @Description:
*/
@Data
@AllArgsConstructor
@ToString
@NoArgsConstructor
public class Person implements Comparable<Person> {
/**
* 名字
*/
private String name;
/**
* 年龄
*/
private int age;
@Override
public int compareTo(Person person) {
return name.compareTo(person.name);
}
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("ccc", 21));
list.add(new Person("aaa", 23));
list.add(new Person("bbb", 19));
Collections.sort(list);
list.stream().forEach(System.out::println);
}
}
输出结果如下:
使用Comparable接口定义排列排序显然有其局限性。对于一个给定的类,只能够实现这个接口一次。如果在一个集合中需要按照年龄降序进行排序,在另一个集合中却要按照年龄升序进行排序,该怎么办呢?另外。如果需要对一个类的对象进行排序,而这个类的创建者又没有实现Comparable接口,又该怎么办呢?这时候就需要用到Comparator接口了。
Comparator
Comparator是比较器接口,使用Comparator要建立一个”该类的比较器“来进行排序。
Comparator接口声明了两个方法:compare和equals。
public interface Comparator<T>(
int compare(T a,T b);
}
与compareTo方法一样,如果a位于b之前compare方法则返回负值;如果a和b相等则返回0,否则返回正值。
下面用一个例子来展示一下如何使用Comparator接口
package entity;
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @Author Lbl
* @Date 2021/12/30 19:22
* @Description:
*/
@Data
@AllArgsConstructor
@ToString
@NoArgsConstructor
public class Person2 {
/**
* 名字
*/
private String name;
/**
* 年龄
*/
private int age;
public static void main(String[] args) {
// 利用匿名内部类的方式,将Person按年龄降序排序
SortedSet<Person> sortedSet1 = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
});
sortedSet1.add(new Person("ccc", 21));
sortedSet1.add(new Person("aaa", 23));
sortedSet1.add(new Person("bbb", 19));
sortedSet1.stream().forEach(System.out::println);
System.out.println("------------------------");
// 利用lamada表达式,将Person按年龄按升序排列
SortedSet<Person> sortedSet2 = new TreeSet<>((p1, p2) -> p2.getAge() - p1.getAge());
sortedSet2.add(new Person("ccc", 21));
sortedSet2.add(new Person("aaa", 23));
sortedSet2.add(new Person("bbb", 19));
sortedSet2.stream().forEach(System.out::println);
}
}
输出结果如下:
在该例中,两个集合分别用了针对Person2的年龄降序和年龄升序来进行排序。可见,Comparator可以对一个类以多种方式进行排序。