Array、List、Stream排序详解
在日常开发中,排序是我们经常遇到的问题,那么java代码如何排序呢?
下文笔者先讲述两个接口,那就是Comparable接口,Comparator接口
可对实现Comparable接口
进行排序
同时还可指定排序的范围
下文笔者先讲述两个接口,那就是Comparable接口,Comparator接口
Comparable接口源码
package java.lang;
public interface Comparable<T> {
public int compareTo(T o);
}
此接口会返回一个整数
返回正数
代表当前对象大于被比较的对象;
返回0
代表当前对象等于于被比较的对象;
返回负数
代表当前对象小于被比较的对象。
注意事项:
1.当实现此接口后
可使用Arrays.sort()和Collections.sort()进行排序
2.常见的类String,Integer,Double,Date等都实现了Comparable接口
例:Date类中Comparable接口的实现源码
public int compareTo(Date anotherDate) {
long thisTime = getMillisOf(this);
long anotherTime = getMillisOf(anotherDate);
return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
}
Comparator接口源码
package java.util;
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
它是一个函数式接口 它的compare方法有两个参数 代表进行比较的两个对象 这个接口代表了可以作为某种对象比较的一种法则 或叫一种策略 它的返回值正负代表意义与Comparable接口的方法一样。
Comparator有三种实现方式
实现类 匿名类 Lambda表达式
数组排序Arrays
Arrays的sort方法可对实现Comparable接口
进行排序
同时还可指定排序的范围
//Arrays.sort对String进行排序
String[] strings = {"de", "dc", "aA", "As", "k", "b"};
Arrays.sort(strings);
assertTrue(Arrays.equals(strings,
new String[]{"As", "aA", "b", "dc", "de", "k"}));
//Arrays.sort指定范围排序
strings = new String[]{"z", "a", "d", "b"};
Arrays.sort(strings, 0, 3);
assertTrue(Arrays.equals(strings,
new String[]{"a", "d", "z", "b"}));
//Arrays.sort对基本类型排序
int[] nums = {3, 1, 20, 2, 38, 2, 94};
Arrays.sort(nums);
assertTrue(Arrays.equals(nums,
new int[]{1, 2, 2, 3, 20, 38, 94}));
//Arrays.parallelSort多线程排序
nums = new int[]{3, 1, 20, 2, 38, 2, 94};
Arrays.parallelSort(nums);
assertTrue(Arrays.equals(nums,
new int[]{1, 2, 2, 3, 20, 38, 94}));
实现类的比较
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Person {
private String name;
private int age;
}
排序
//Arrays.sort提供Comparator进行排序
Person[] persons = new Person[]{
new Person("Larry", 18),
new Person("David", 30),
new Person("James", 20),
new Person("Harry", 18)};
Arrays.sort(persons, Comparator.comparingInt(Person::getAge));
assertTrue(Arrays.equals(persons, new Person[]{
new Person("Larry", 18),
new Person("Harry", 18),
new Person("James", 20),
new Person("David", 30)}));
list排序Collections
对实现Comparable的类进行排序
//Collections.sort对于实现Comparable的类进行排序
List<String> names = asList("Larry", "Harry", "James", "David");
Collections.sort(names);
assertEquals(names, asList("David", "Harry", "James", "Larry"));
使用Comparator排序
//Collections.sort提供Comparator进行排序
List<Person> persons2 = asList(
new Person("Larry", 18),
new Person("David", 30),
new Person("James", 20),
new Person("Harry", 18));
Collections.sort(persons2, Comparator.comparingInt(Person::getAge));
assertEquals(persons2, asList(
new Person("Larry", 18),
new Person("Harry", 18),
new Person("James", 20),
new Person("David", 30)));
List排序
List接口有sort(Comparator<? super E> c)方法 可以实现对自身的排序,会影响自身的顺序。//List.sort排序
names = asList("Larry", "Harry", "James", "David");
names.sort(Comparator.naturalOrder());
assertEquals(names, asList("David", "Harry", "James", "Larry"));
Stream排序
Stream提供sorted()和sorted(Comparator<? super T> comparator)进行排序,会返回一个新的Stream。
//Stream.sorted排序
names = asList("Larry", "Harry", "James", "David");
List<String> result = names.stream()
.sorted()
.collect(Collectors.toList());
assertEquals(result, asList("David", "Harry", "James", "Larry"));
//Stream.sorted提供Comparator排序
names = asList("Larry", "Harry", "James", "David");
result = names.stream()
.sorted(Comparator.naturalOrder())
.collect(Collectors.toList());
assertEquals(result, asList("David", "Harry", "James", "Larry"));
单字段排序
对类单字段进行排序,使用以下方式即可
Comparator.comparing(类名::属性getter)
//排序后,反转
Comparator.comparing(类名::属性getter).reversed()
或Comparator.comparing(类名::属性getter, Comparator.reverseOrder())
例
//单字段排序-升序
List<Person> personList = asList(
new Person("Larry", 18),
new Person("David", 30),
new Person("David", 3),
new Person("James", 20),
new Person("Harry", 18));
List<Person> personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("David", 30),
new Person("David", 3),
new Person("Harry", 18),
new Person("James", 20),
new Person("Larry", 18)));
//单字段排序-倒序1
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName).reversed())
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("Larry", 18),
new Person("James", 20),
new Person("Harry", 18),
new Person("David", 30),
new Person("David", 3)));
//单字段排序-倒序2
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder()))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("Larry", 18),
new Person("James", 20),
new Person("Harry", 18),
new Person("David", 30),
new Person("David", 3)));
多字段排序
使用thenComparing进行连接即可 Comparator.comparing(类名::属性一getter).thenComparing(类名::属性二getter)例
//多字段排序-1升2升
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName)
.thenComparing(Person::getAge))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("David", 3),
new Person("David", 30),
new Person("Harry", 18),
new Person("James", 20),
new Person("Larry", 18)));
//多字段排序-1升2倒
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName)
.thenComparing(Person::getAge, Comparator.reverseOrder()))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("David", 30),
new Person("David", 3),
new Person("Harry", 18),
new Person("James", 20),
new Person("Larry", 18)));
//多字段排序-1倒2升
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder())
.thenComparing(Person::getAge))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("Larry", 18),
new Person("James", 20),
new Person("Harry", 18),
new Person("David", 3),
new Person("David", 30)));
//多字段排序-1倒2倒
personResult = personList.stream()
.sorted(Comparator.comparing(Person::getName, Comparator.reverseOrder())
.thenComparing(Person::getAge, Comparator.reverseOrder()))
.collect(Collectors.toList());
assertEquals(personResult, asList(
new Person("Larry", 18),
new Person("James", 20),
new Person("Harry", 18),
new Person("David", 30),
new Person("David", 3)));
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


