那么,下面这个方法的输出结果是什么?
Collections.sort(list,Comparator.comparingInt(String::length).thenComparing(Comparator.comparing(String::toLowerCase,Comparator.reverseOrder())));再次重复一下:前面比较器的结果等于0,这个thenComparing()才会被调用. 就如三个长度相同的那三个数,才会被二次排序.也就是说如果第一个比较器,能够排序,就用第一个,第一个排序不成再用第二个.
多级排序
Collections.sort(list,Comparator.comparingInt(String::length).reversed() .thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder())) .thenComparing(Comparator.reverseOrder()));JDK1.8之前,Collections里面提供的方法是很少的,从JDK1.8之后,新增了大量的实现方法和具体的特化的实现.
避免了装箱和拆箱操作.这也可能会影响性能.
自定义Collector实现类实现Collector接口
public interface Collector<T, A, R> { Supplier<A> supplier(); BiConsumer<A, T> accumulator(); BinaryOperator<A> combiner(); Function<A, R> finisher(); Set<Characteristics> characteristics(); public static<T, R> Collector<T, R, R> of(Supplier<R> supplier, BiConsumer<R, T> accumulator, BinaryOperator<R> combiner, Characteristics... characteristics) { Objects.requireNonNull(supplier); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); Objects.requireNonNull(characteristics); Set<Characteristics> cs = (characteristics.length == 0) ? Collectors.CH_ID : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, characteristics)); return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs); } public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner, Function<A, R> finisher, Characteristics... characteristics) { Objects.requireNonNull(supplier); Objects.requireNonNull(accumulator); Objects.requireNonNull(combiner); Objects.requireNonNull(finisher); Objects.requireNonNull(characteristics); Set<Characteristics> cs = Collectors.CH_NOID; if (characteristics.length > 0) { cs = EnumSet.noneOf(Characteristics.class); Collections.addAll(cs, characteristics); cs = Collections.unmodifiableSet(cs); } return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs); } Characteristics { CONCURRENT, UNORDERED, IDENTITY_FINISH } }自定义的收集器
package com.dawa.jdk8.stream2; import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import static java.util.stream.Collector.Characteristics.IDENTITY_FINISH; public class MySetCollector<T> implements Collector<T,Set<T>,Set<T>> { @Override public Supplier<Set<T>> supplier() { System.out.println("supplier invoked"); return HashSet<T>::new;// 返回一个HasHSet容器. } @Override public BiConsumer<Set<T>, T> accumulator() { System.out.println("accumalator invoked");//累加器 return Set<T>::add; // return HashSet<T>::add; //不行,没有静态方法支持. 应该是 Supplier返回值的父类接口. 不能使用具体类型的set. } @Override public BinaryOperator<Set<T>> combiner() { System.out.println("combiner invoked");//并行流的时候,合并中间结果 return (set1,set2)->{ set1.addAll(set2);return set1; }; } @Override public Function<Set<T>, Set<T>> finisher() {//合并结果类型.结果容器 System.out.println("finisher invoked"); // return ts -> ts; return Function.identity(); //底层是一样的. 同一性. } @Override public Set<Characteristics> characteristics() { System.out.println("charcteristics invoked "); return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH)); } public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "welcome"); Set<String> collect = list.stream().collect(new MySetCollector<>()); System.out.println(collect); } } 从源码深入Collector 第一步:代码中调用collect() public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "welcome"); Set<String> collect = list.stream().collect(new MySetCollector<>()); System.out.println(collect); } 第二步:collect()方法的实现类 @Override @SuppressWarnings("unchecked") public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) { A container; if (isParallel() && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) { container = collector.supplier().get(); BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator(); forEach(u -> accumulator.accept(container, u)); } else { container = evaluate(ReduceOps.makeRef(collector)); } return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH) ? (R) container : collector.finisher().apply(container); }