章
目
录
Java Comparable接口是集合框架的一部分。学习Comparable接口的目的并在不同场景中使用它。
1.Comparable接口
1.1. 为什么要实现Comparable?
在Java中,如果我们想对元素列表进行排序,我们可以使用Collections.sort()方法。它根据自然顺序对列表项进行排序。所有Java包装类、日期时间类和字符串等都实现了Comparable接口,因此它们都有自然顺序定义。
例如,java.lang.String类的自然顺序是字典顺序。因此,如果我们对字符串对象列表进行排序,它们将按照字典中的顺序进行排序。类似地,整数对象将按升序进行排序,自然地。
但是,我们需要定义我们在应用程序中创建的自定义领域类的自然排序。例如,Employee、Order等。如果我们想使用Collections.sort()方法或任何期望列表项是Comparable的方法对员工或订单列表进行排序,这是必需的。
因此,Comparable接口的主要目的是定义实现它的类的自然排序顺序。
1.2. 实现Comparable
Comparable接口有一个抽象方法compareTo(),对象需要实现它以具有自然排序。
- 对象必须是可相互比较的,不得对集合中的任何键引发ClassCastException异常。
- compareTo()方法必须根据此对象是否小于、等于或大于指定对象返回负整数、零或正整数。
- 请注意,如果y.compareTo(x)引发异常,compareTo()必须引发异常。
- 另外,可比较对象之间的关系必须是传递性的,即(x.compareTo(y) > 0 && y.compareTo(z) > 0)意味着x.compareTo(z) > 0。
- null不是任何类的实例,因此e.compareTo(null)应引发NullPointerException。
public interface Comparable<T>
{
public int compareTo(T o);
}
例如,对于Employee类,自然排序可以基于id字段。
import java.time.LocalDate;
public class Employee implements Comparable<Employee> {
private Long id;
private String name;
private LocalDate dob;
@Override
public int compareTo(Employee o)
{
return this.getId().compareTo( o.getId() );
}
}
使用Comparable接口,我们可以对所有类型的对象进行排序,包括字符串、包装类或自定义对象。
另请参阅:使用Comparable和Comparator进行排序
2.使用Comparable
我们可以使用实现Comparable接口的对象进行排序,以下是几种方法:
2.1. Collections.sort()和Arrays.sort()
- 使用Collections.sort()方法对对象列表进行排序。
- 使用Arrays.sort()方法对对象数组进行排序。
Collections.sort(items);
Arrays.sort(items);
2.2. Collections.reverseOrder()
此实用方法返回一个Comparator,对对象集合实施自然顺序的逆序。
这使得对实现Comparable接口的对象集合(或数组)进行排序(或维护)变得非常简单,以逆自然顺序。
Collections.sort(items, Collections.reverseOrder());
Arrays.sort(items, Collections.reverseOrder());
2.3. 有序集合
实现此接口的对象可以用作有序map中的键或有序set中的元素(例如TreeSet),无需指定比较器。
// 所有元素自动排序
SortedSet<Item> itemsSet = new TreeSet<>();
2.4. Stream流
Stream.sorted()可用于对实现Comparable接口的对象流进行排序。但请注意,stream.sorted()不会对原始集合进行排序,只会对流中的项目进行排序。
items.stream()
.sorted()
.forEach(i -> System.out.println(i);
3. Comparable示例
所有给定示例都使用Collections.sort()方法对列表进行排序。如果需要对对象数组进行排序,只需将Collections.sort()替换为Arrays.sort()。
3.1. 对字符串进行排序
使用Comparable接口对字符串列表进行排序的Java程序。
ArrayList<String> list = new ArrayList<>();
list.add("E");
list.add("A");
list.add("C");
list.add("B");
list.add("D");
Collections.sort(list);
System.out.println(list);// [A, B, C, D, E]
3.2. 以逆序对字符串进行排序
使用Comparable接口对字符串列表进行逆序排序的Java程序。
ArrayList<String> list = new ArrayList<>();
list.add("E");
list.add("A");
list.add("C");
list.add("B");
list.add("D");
//逆排序
Collections.sort(list, Collections.reverseOrder());
System.out.println(list);// [E, D, C, B, A]
3.3. 对整数进行排序
使用Comparable接口对整数列表进行排序,包括自然顺序和逆序。
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(300);
list.add(45);
list.add(2);
list.add(5);
//自然排序
Collections.sort(list);
System.out.println(list); //[2, 5, 10, 45, 300]
//逆序
Collections.sort(list, Collections.reverseOrder());
System.out.println(list); // [300, 45, 10, 5, 2]
3.4. 对自定义对象列表进行排序
在此示例中,我们正在按id对员工列表进行排序。
ArrayList<Employee> list = new ArrayList<>();
list.add(new Employee(22l, "Lokesh", LocalDate.now()));
list.add(new Employee(18l, "Alex", LocalDate.now()));
list.add(new Employee(30l, "Bob", LocalDate.now()));
list.add(new Employee(600l, "Charles", LocalDate.now()));
list.add(new Employee(5l, "David", LocalDate.now()));
//自然排序
Collections.sort(list);
System.out.println(list);
//逆序
Collections.sort(list, Collections.reverseOrder());
System.out.println(list);
程序输出:
[
Employee [id=5, name=David, dob=2018-10-29],
Employee [id=18, name=Alex, dob=2018-10-29],
Employee [id=22, name=Lokesh, dob=2018-10-29],
Employee [id=30, name=Bob, dob=2018-10-29],
Employee [id=600, name=Charles, dob=2018-10-29]
]
//逆序
[
Employee [id=600, name=Charles, dob=2018-10-30],
Employee [id=30, name=Bob, dob=2018-10-30],
Employee [id=22, name=Lokesh, dob=2018-10-30],
Employee [id=18, name=Alex, dob=2018-10-30],
Employee [id=5, name=David, dob=2018-10-30]
]
4. 结论
在本教程中,我们学习了Comparable接口。此接口有助于对具有简单接口实现的对象强加自然顺序。我们还学习了如何对Java中的字符串列表、字符串数组、整数列表和整数数组进行排序。我们学习了如何使用Comparable在Java中对Employee对象进行排序。