对于有序流,排序是稳定的。对于非有序流,不保证排序稳定。
  String[] arr = new String[]{"b_123","c+342","b#632","d_123"};List<String> l  = Arrays.stream(arr)        .sorted((s1,s2) -> {            if (s1.charAt(0) == s2.charAt(0))                return s1.substring(2).compareTo(s2.substring(2));            else                return s1.charAt(0) - s2.charAt(0);        })        .collect(Collectors.toList());System.out.println(l); //[b_123, b#632, c+342, d_123]
  skip
  skip返回丢弃了前n个元素的流,如果流中的元素小于或者等于n,则返回空的流。
  终点操作 terminal operations
  Match
  public boolean  allMatch(Predicate<? super T> predicate)public boolean  anyMatch(Predicate<? super T> predicate)public boolean  noneMatch(Predicate<? super T> predicate)
  这一组方法用来检查流中的元素是否满足断言。
  allMatch只有在所有的元素都满足断言时才返回true,否则flase,流为空时总是返回true
  anyMatch只有在任意一个元素满足断言时返回true,否则flase,
  noneMatch只有在所有的元素都不满足断言时才返回true,否则flase,
  System.out.println(Stream.of(1,2,3,4,5).allMatch( i -> i > 0)); //true      System.out.println(Stream.of(1,2,3,4,5).anyMatch( i -> i > 0)); //true      System.out.println(Stream.of(1,2,3,4,5).noneMatch( i -> i > 0)); //falseSystem.out.println(Stream.<Integer>empty().allMatch( i -> i > 0)); //true      System.out.println(Stream.<Integer>empty().anyMatch( i -> i > 0)); //false      System.out.println(Stream.<Integer>empty().noneMatch( i -> i > 0)); //true
  count
  count方法返回流中的元素的数量。它实现为:
  mapToLong(e -> 1L).sum();
  collect
  <R,A> R  collect(Collector<? super T,A,R> collector)<R> R  collect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)
  使用一个collector执行mutable reduction操作。辅助类 Collectors 提供了很多的collector,可以满足我们日常的需求,你也可以创建新的collector实现特定的需求。它是一个值得关注的类,你需要熟悉这些特定的收集器,如聚合类averagingInt、大小值maxByminBy、计数counting、分组groupingBy、字符串连接joining、分区partitioningBy、汇总summarizingInt、化简reducing、转换toXXX等。
  第二个提供了更底层的功能,它的逻辑类似下面的伪代码:
  R result = supplier.get();for (T element : this stream)    accumulator.accept(result, element);return result;
  例子:
  List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add,                                           ArrayList::addAll);String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,                                     StringBuilder::append)                            .toString();
  find
  findAny()返回任意一个元素,如果流为空,返回空的Optional,对于并行流来说,它只需要返回任意一个元素即可,所以性能可能要好于findFirst(),但是有可能多次执行的时候返回的结果不一样。findFirst()返回第一个元素,如果流为空,返回空的Optional。
  forEach、forEachOrdered
  forEach遍历流的每一个元素,执行指定的action。它是一个终点操作,和peek方法不同。这个方法不担保按照流的encounter order顺序执行,如果对于有序流按照它的encounter order顺序执行,你可以使用forEachOrdered方法。
  Stream.of(1,2,3,4,5).forEach(System.out::println);
  大小值
  max返回流中的大值,min返回流中的小值。
  reduce
  reduce是常用的一个方法,事实上很多操作都是基于它实现的。它有几个重载方法:
  pubic Optional<T>  reduce(BinaryOperator<T> accumulator)pubic T  reduce(T identity, BinaryOperator<T> accumulator)pubic <U> U  reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
  第一个方法使用流中的第一个值作为初始值,后面两个方法则使用一个提供的初始值。
  Optional<Integer> total = Stream.of(1,2,3,4,5).reduce( (x, y) -> x +y);Integer total2 = Stream.of(1,2,3,4,5).reduce(0, (x, y) -> x +y);
  值得注意的是accumulator应该满足结合性(associative)。
  toArray()
  将流中的元素放入到一个数组中。
  组合
  concat用来连接类型一样的两个流。
  public static <T> Stream<T>  concat(Stream<? extends T> a, Stream<? extends T> b)
  “
  转换
  toArray方法将一个流转换成数组,而如果想转换成其它集合类型,西需要调用collect方法,利用Collectors.toXXX方法进行转换:
  public static <T,C extends Collection<T>> Collector<T,?,C>  toCollection(Supplier<C> collectionFactory)public static ……  toConcurrentMap(……)public static <T> Collector<T,?,List<T>>  toList()public static ……  toMap(……)public static <T> Collector<T,?,Set<T>>  toSet()
  更进一步
  虽然Stream提供了很多的操作,但是相对于Scala等语言,似乎还少了一些。一些开源项目提供了额外的一些操作,比如 protonpack 项目提供了下列方法:
  takeWhile and takeUntil
  skipWhile and skipUntil
  zip and zipWithIndex
  unfold
  MapStream
  aggregate
  Streamable
  unique collector
  java8-utils 也提供了一些有益的辅助方法。