今天我们将研究Java集合的排序方法。在与java中的集合,我们经常需要对数据进行排序。
Java Collections类为我们提供了非常方便的方法Collections.sort()
对所有进行排序List实施例如链表 and 数组列表。有两个超载Collections.sort()
方法,它们是:
-
sort(List list)
:按自然顺序的升序对列表中的元素进行排序。
-
sort(List list, Comparator c)
:按照列表中元素的顺序对列表中的元素进行排序比较器.
注意上述方法签名使用generics但为了阅读方便,我在这里删除了它们。让我们一一深入探讨如何以及何时使用这两种方法。
考虑一个ArrayList
of String
:
List<String> fruits = new ArrayList<String>();
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Banana");
fruits.add("Grape");
现在,我们将使用它进行排序Collections.sort()
:
Collections.sort(fruits);
// Print the sorted list
System.out.println(fruits);
该程序的输出将是:
[Apple, Banana, Grape, Orange]
因此,我们可以看到Collections.sort()
已按词汇顺序对字符串列表进行排序。它不会返回任何东西。如果我们有一个自定义对象列表怎么办?当然,我们也可以对它们进行排序。考虑一类水果:
package com.journaldev.collections;
public class Fruit{
private int id;
private String name;
private String taste;
Fruit(int id, String name, String taste){
this.id=id;
this.name=name;
this.taste=taste;
}
}
让我们创建一个水果列表:
List<Fruit> fruitList=new ArrayList<Fruit>();
Fruit apple=new Fruit(1, "Apple", "Sweet");
Fruit orange=new Fruit(2, "Orange", "Sour");
Fruit banana=new Fruit(4, "Banana", "Sweet");
Fruit grape=new Fruit(3, "Grape", "Sweet and Sour");
fruitList.add(apple);
fruitList.add(orange);
fruitList.add(banana);
fruitList.add(grape);
In order to sort this list, if we directly use the Collections.sort(List list)
, it will give a Compile Time Error because there is no natural ordering defined for the Fruit objects. So, it doesn’t know how to sort this list. For objects to have a natural order they must implement the interface java.lang.Comparable. The Comparable
interface has a method compareTo()
, which returns a negative, 0, a positive if the current value is less than, equal to, or greater than the value we are comparing with, respectively. Let’s enhance the Fruit class to implement Comparable
interface. We are defining that the natural order of sorting is based on the “id” field of Fruit:
package com.journaldev.collections;
public class Fruit implements Comparable<Object>{
private int id;
private String name;
private String taste;
Fruit(int id, String name, String taste){
this.id=id;
this.name=name;
this.taste=taste;
}
@Override
public int compareTo(Object o) {
Fruit f = (Fruit) o;
return this.id - f.id ;
}
}
现在我们已经实施了Comparable
,我们可以对列表进行排序而不会出现任何错误:
Collections.sort(fruitList);
fruitList.forEach(fruit -> {
System.out.println(fruit.getId() + " " + fruit.getName() + " " +
fruit.getTaste());
});
输出如下:
1 Apple Sweet
2 Orange Sour
3 Grape Sweet and Sour
4 Banana Sweet
为了定义与元素的自然排序不同的自定义排序逻辑,我们可以实现java.util.Comparator
接口并传递它的实例作为第二个参数sort()
。让我们考虑一下,我们想要根据水果的“名称”字段来定义排序。我们实施Comparator
,并在其compare()
方法中,我们需要编写比较的逻辑:
package com.journaldev.collections;
class SortByName implements Comparator<Fruit> {
@Override
public int compare(Fruit a, Fruit b) {
return a.getName().compareTo(b.getName());
}
}
现在,我们可以使用这个比较器对其进行排序:
Collections.sort(fruitList, new SortByName());
输出如下:
1 Apple Sweet
4 Banana Sweet
3 Grape Sweet and Sour
2 Orange Sour
我们也可以在运行时提供排序逻辑,而不是使用 lambda 函数为 Comparator 编写新类:
Collections.sort(fruitList, (a, b) -> {
return a.getName().compareTo(b.getName());
});
默认情况下,Collection.sort
按升序执行排序。如果我们想以相反的顺序对元素进行排序,我们可以使用以下方法:
-
reverseOrder()
:返回一个Comparator
这强制了集合元素的自然顺序相反。
-
reverseOrder(Comparator cmp)
:返回一个Comparator
这对指定的比较器施加了相反的排序。
以下是这两种方法的示例:
Collections.sort(fruits, Collections.reverseOrder());
System.out.println(fruits);
它将按相反的字母顺序输出水果:
[Orange, Grape, Banana, Apple]
Collections.sort(fruitList, Collections.reverseOrder(new SortByName()));
fruitList.forEach(fruit -> {
System.out.println(fruit.getId() + " " + fruit.getName() + " " +
fruit.getTaste());
});
Output:
2 Orange Sour
3 Grape Sweet and Sour
4 Banana Sweet
1 Apple Sweet
这就是 Java 集合 sort() 方法及其示例的全部内容。参考:API Doc