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)));
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。