JAVA8学习——深入Comparator&Collector(学习过程)

深入Comparator&Collector 从源码深入Comparator

Comparator从Java1.2就出来了,但是在1.8的时候,又添加了大量的默认方法.

compare() equals() reversed() //倒序 thenComparing(Comparator<? super T> other) //然后,再去比较. thenComparing( Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator) //先通过第一个比较器,再执行第二个比较器...串联 thenComparing() thenComparingInt() thenComparingLong() thenComparingDouble() reverseOrder() naturalOrder() nullsFirst() nullsLast() comparing () //静态方法 comparing() comparingInt() comparingLong() comparingDouble()

### 从Demo代码看Comparator

package com.dawa.jdk8.stream2; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; //关于比较器comparator,案例详解. public class MyComparator { public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "welcome", "nihao"); //按照字母排序 Collections.sort(list); System.out.println(list); //按照字符串的长度. Collections.sort(list, (item1, item2) -> item1.length() - item2.length()); System.out.println(list); //按照字符串的长度降序排序. Collections.sort(list, (item1, item2) -> item2.length() - item1.length()); //使用方法引用 //长度排序 Collections.sort(list, Comparator.comparingInt(String::length)); System.out.println(list); //长度倒叙排序 Collections.sort(list, Comparator.comparingInt(String::length).reversed()); System.out.println(list); //使用lambda表达式实现上述两个方法 // Collections.sort(list,Comparator.comparingInt(item->item.length()).reversed()); //这里,reversed()方法,参数要的是Object类型. //参数的类型推断. Collections.sort(list,Comparator.comparingInt((String item)->item.length()).reversed()); //这样写就行了. //问题:之前为什么会成功? 因为是从Stream<T> 类型开始推断的,可以获取到原属性的元素. //问题:为什么上述的类型推断失败了/? 看sort方法的 Comparator类的泛型<T>,T是传入参数的泛型- <? super T>. // String上的类型.你没指定,编译器也没办法帮你指定. // public static <T> void sort(List<T> list, Comparator<? super T> c) { // list.sort(c); // } //如: Collections.sort(list,Comparator.comparingInt((Boolean item)->1).reversed()); //这样不会被兼容.因为Boolean 不是 String的上类型. //如: Collections.sort(list,Comparator.comparingInt((Object item)->1).reversed()); //这样就是可以的. //如: Collections.sort(list,Comparator.comparingInt(item->item.length()); //这样也是可以的. } } @SuppressWarnings({"unchecked", "rawtypes"}) public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); }

关于: <? super T> 泛型的使用.需要注意.

语义更宽泛,但是从实际结果类型,实际就是T类型本身.这个需要仔细思考一下.

Comparator比较器的串联使用 //通过两层比较,1:排序(升序) ,2:字母顺序排序. 使用thenComparing() Collections.sort(list,Comparator.comparingInt(String::length).thenComparing(String.CASE_INSENSITIVE_ORDER));

thenComparing()方法源码如下

/** * Returns a lexicographic-order comparator with another comparator. * If this {@code Comparator} considers two elements equal, i.e. * {@code compare(a, b) == 0}, {@code other} is used to determine the order. * * <p>The returned comparator is serializable if the specified comparator * is also serializable. * * @apiNote * For example, to sort a collection of {@code String} based on the length * and then case-insensitive natural ordering, the comparator can be * composed using following code, * 不区分大小写,的实现. 技术上述案例. * <pre>{@code * Comparator<String> cmp = Comparator.comparingInt(String::length) * .thenComparing(String.CASE_INSENSITIVE_ORDER); * }</pre> * * @param other the other comparator to be used when this comparator * compares two objects that are equal. * @return a lexicographic-order comparator composed of this and then the * other comparator * @throws NullPointerException if the argument is null. * @since 1.8 */ default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator<T> & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; }

前面比较器的结果等于0,这个thenComparing()才会被调用. 就如三个长度相同的那三个数,才会被二次排序.

也就是说如果第一个比较器,能够排序,就用第一个,第一个排序不成再用第二个.

另一种实现

Collections. sort(list,Comparator.comparingInt(String::length). thenComparing((item1,item2)->item1.toLowerCase().compareTo(item2)));

另一种实现

Collections.sort(list,Comparator.comparingInt(String::length).thenComparing(Comparator.comparing(String::toUpperCase)));

另一种实现

Collections.sort(list,Comparator.comparingInt(String::length).thenComparing(Comparator.comparing(String::toLowerCase,Comparator.reverseOrder())));

上述几个案例,主要就是对于 thenComparing()方法的不同使用实现.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpysfj.html