Java集合sort()
今天,我们将研究Java Collections的排序方法。
在Java中使用Collections时,我们不仅仅需要对数据进行排序。
Java集合sort()
Java Collections类为我们提供了一个非常方便的方法Collections.sort()来对所有List实现(例如LinkedList和ArrayList)进行排序。
有两个重载的Collections.sort()方法,它们是:
sort(List list)
:按照其自然顺序的升序对List的元素进行排序。sort(List list,Comparator c):根据比较器产生的顺序对列表中的元素进行排序。
请注意,上述方法签名使用了泛型,但为了简化阅读,此处已将其删除。
让我们一个一个地探讨如何以及何时使用这两种方法。
Java Collections排序(列表)
考虑一下String
的ArrayList
:
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()
已按词汇顺序对String列表进行了排序。
它不返回任何东西。
如果我们有一个自定义对象列表,该怎么办?当然,我们也可以对它们进行排序。
考虑一类水果:
package com.theitroad.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);
为了对该列表进行排序,如果我们直接使用Collections.sort(List list)
,则会出现"编译时错误",因为没有为Fruit对象定义自然排序。
因此,它不知道如何对该列表进行排序。
为了使对象具有自然顺序,它们必须实现接口java.lang.Comparable。
"可比较"接口具有方法" compareTo()",该方法将返回负数,0;如果当前值分别小于,等于或者大于我们要比较的值,则返回正数。
让我们增强Fruit类,以实现"可比较"接口。
我们定义自然排序的顺序是基于Fruit的" id"字段:
package com.theitroad.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集合排序(列表列表,比较器c)
为了定义一种不同于元素自然排序的自定义逻辑,我们可以实现java.util.Comparator接口,并将其实例作为sort()的第二个参数传递。
让我们考虑我们要基于"水果"的"名称"字段定义排序。
我们实现了"比较器",并在其"比较"方法中,需要编写比较逻辑:
package com.theitroad.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()); });
Java Collections.reverseOrder
默认情况下,Collection.sort
以升序执行排序。
如果我们想以相反的顺序对元素进行排序,则可以使用以下方法:
reverseOrder()
:返回一个Comparator
,它强加了集合元素自然排序的顺序。reverseOrder(Comparator cmp)
:返回一个" Comparator",对指定的比较器施加反向排序。
这是这两种方法的示例:
Java Collections reverseOrder()示例
Collections.sort(fruits, Collections.reverseOrder()); System.out.println(fruits);
它将以相反的字母顺序输出水果:
[Orange, Grape, Banana, Apple]
Java Collections reverseOrder(Comparator cmp)示例
Collections.sort(fruitList, Collections.reverseOrder(new SortByName())); fruitList.forEach(fruit -> { System.out.println(fruit.getId() + " " + fruit.getName() + " " + fruit.getTaste()); });
输出:
2 Orange Sour 3 Grape Sweet and Sour 4 Banana Sweet 1 Apple Sweet