在前一篇文章浅析Java中的Steam流中讲述了流式思想和Java中更适用于函数式编程的Stream流,以及Stream流中的一些常用方法,如forEach()filter()map()count()limit()skip()concat() 。本文中将讲述Stream中更多的方法,以及java.util.stream包下更多类型的Stream。


1. 创建Stream流

前一篇文章中介绍了最为常用的两个创建Stream流的方法,即:

  • Collection集合的`stream() 获取集合对应的Stream流
    • 使用Stream.of()创建包含多个数据的Stream流

除此之外,Stream中还有更多用于创建流的方法,如:

  • static <T> Stream<T> empty() 用于创建一个空流
  • static <T> Stream<T> generate(Supplier<? extends T> s):创建一个无限流,流中的元素通过反复调用s函数产生
  • static <T> Stream<T> iterate(T seed, UnaryOperator<T> f):创建一个无限流,参数包含seed、在seed上调用f产生的值、在前一个元素上调用f产生的值
  • static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next):类似于上一个方法,不同之处在于流会在遇到的第一个不满足hasNext条件时终止
  • static <T> Stream<T> ofNullable(T t):返回含单个元素的流```java import java.math.BigInteger; import java.util.*; import java.util.stream.Stream;

public class SomeMethodsAboutGetStream { public static void main(String[] args) { // 创建空流 final Stream empty = Stream.empty(); empty.forEach(k-> System.out.println(k)); // System.out.println(“—————————-“);

  1. // 创建无限流
  2. BigInteger limit = new BigInteger("1000000");
  3. Stream.generate(()->"Hello").limit(5).forEach(k -> System.out.println(k));
  4. Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)).limit(5).forEach(System.out::println);
  5. System.out.println("-------------------");
  6. Stream<Object> s15 = Stream.ofNullable(10);
  7. s15.forEach(System.out::println); // 10
  8. System.out.println("-------------------");
  9. }

}

  1. <a name="ea8c537f"></a>
  2. ### 2. 抽取子流和组合流
  3. 类如之前的`limit()`、`skip()`和`cooncat()`都属于此类范畴的方法,它们会返回一个包含部分元素的新流。除此之外,相关的方法还有:
  4. - `default Stream<T> takeWhile(Predicate<? super T> predicate)`:产生一个流,流中的元素满足传入的谓词条件
  5. - `default Stream<T> dropWhile(Predicate<? super T> predicate)`:产生一个流,流的元素是当前流中排除不满足谓词条件的元素之外的所有元素
  6. ```java
  7. import java.math.BigInteger;
  8. import java.util.*;
  9. import java.util.stream.Stream;
  10. public class SomeMethodsAboutGetStream {
  11. public static void main(String[] args) {
  12. Stream<String> s0 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
  13. Stream<String> s1 = Stream.of("Forlogen", "Kobe", "James", "Bill");
  14. s0.takeWhile(ss -> ss.startsWith("F")).forEach(System.out::println); // Forlogen
  15. s1.dropWhile(ss -> ss.startsWith("F")).forEach(System.out::println); // Kobe James Bill
  16. System.out.println("-------------------");
  17. }
  18. }

3. 流的约简

  • Stream<T> distinct ():返回一个流,元素为原来流中的元素剔除重复元素后的结果
  • Stream<T> sorted ():按照自然序就行排列,如String按照字典序排序,数值型按照大小排序,排序的元素要实现Comparable接口
  • Stream<T> sorted (Comparator<? super T> comparator):根据传入的Comparator指定的顺序就行排列,返回一个新的流> 对于数值型数据,程序按数值大小进行排序

    对于String类型数据,程序按照字典序进行排序

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Stream;

public class SomeMethodsAboutGetStream {
    public static void main(String[] args) {
        Stream<String> s2 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forlogen","Forlogen");
        s2.distinct().forEach(System.out::println);
        System.out.println("-------------------"); // Forlogen  Kobe  James  Bill

        Stream<String> s3 = Stream.of("Forlogen", "Kobe", "James", "Bill");
        s3.sorted().forEach(System.out::println);
        System.out.println("-------------------");  // Bill Forlogen James  Kobe
        Stream<Integer> s4 = Stream.of(3, 1, 10, 7, 4);
        s4.sorted().forEach(System.out::println);  // 1 3 4 7 10
        System.out.println("-------------------");
        Stream<Integer> s5 = Stream.of(3, 1, 10, 7, 4);
        s5.sorted(Comparator.comparing(Integer::intValue).reversed()).forEach(System.out::println); // 10 7 4 3 1
        System.out.println("-------------------");

    }
}

4. 获取流中信息

之前已经学习过通过count()来获取流中元素的个数,此外还有如下的方法可以获取流中数据的一些其他信息:

  • Optional<T> max(Comparator<? super T> comparator)
  • Optional<T> min(Comparator<? super T> comparator)
  • Optional<T> findFirst()
  • Optional<T> findAny()
  • boolean anyMatch (Predicate<? super T> predicate) 流中存在匹配条件的元素时返回true
  • boolean allMatch (Predicate<? super T> predicate): 流中任意一个元素都匹配条件时返回true
  • boolean noneMatch (Predicate<? super T> predicate): 流中没有一个元素匹配条件时返回true
  • Object[] oArray(): 返回对象数组
  • <A> A[] toArray (IntFunction<A[]> generator):返回A类型的数组
  • Optional<T> reduce (BinaryOperator<T> accumulator):用给定的accumulator产生流中元素的累积总和
  • void forEachOrdered(Consumer<? super T> action): 为该流的每个元素执行一个操作,如果该流具有已定义的相遇顺序,则按照该流的相遇顺序执行
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Stream;

public class SomeMethodsAboutGetStream {
    public static void main(String[] args) {
        Stream<Integer> s6 = Stream.of(3, 1, 10, 7, 4);
        Optional<Integer> min = s6.min(Comparator.comparing(Integer::intValue));
        System.out.println(min.get());  // 1
        System.out.println("-------------------");
        Stream<Integer> s7 = Stream.of(3, 1, 10, 7, 4);
        Optional<Integer> max = s7.max(Comparator.comparing(Integer::intValue));
        System.out.println(max.get());  // 10
        System.out.println("-------------------");

        Stream<String> s8 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s8.takeWhile(ss -> ss.startsWith("F")).findFirst().get()); // Forlogen
        System.out.println("-------------------");
        Stream<String> s9 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s9.takeWhile(ss -> ss.startsWith("F")).findAny().get()); // Forlogen
        System.out.println("-------------------");

        Stream<String> s10 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        Stream<String> s11 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        Stream<String> s12 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s10.anyMatch(s -> s.startsWith("F"))); // true
        System.out.println(s11.allMatch(s -> s.startsWith("F"))); // false
        System.out.println(s12.noneMatch(s -> s.startsWith("F"))); // false
        System.out.println("-------------------");

        Stream<String> s13 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(Arrays.toString(s13.takeWhile(s -> s.startsWith("F")).toArray())); // [Forlogen]
        Stream<String> s14 = Stream.of("Forever", "Kobe", "James", "Bill");
        System.out.println(Arrays.toString(s14.takeWhile(s -> s.length() > 4).toArray(String[]::new)));  // [Forever]
        System.out.println("-------------------");

        Stream<Object> s15 = Stream.ofNullable(10);
        s15.forEach(System.out::println);  // 10
        System.out.println("-------------------");

        Stream<Integer> s16 = Stream.of(3, 1, 10, 7, 4);
        System.out.println(s16.reduce(Integer::sum).get()); // 25
        System.out.println("-------------------");

        Stream<Integer> s17 = Stream.of(3, 1, 10, 7, 4);
        s17.forEach(System.out::println);
        System.out.println("-------------------");
        Stream<Integer> s18 = Stream.of(3, 1, 10, 7, 4);
        s18.forEachOrdered(System.out::println);
    }
}

5. 完整实验代码

import java.math.BigInteger;
import java.util.*;
import java.util.stream.Stream;

public class SomeMethodsAboutGetStream {
    public static void main(String[] args) {
        // 创建空流
        final Stream<Object> empty = Stream.empty();
        empty.forEach(k-> System.out.println(k)); //
        System.out.println("-------------------");

        // 创建无限流
        BigInteger limit = new BigInteger("1000000");
        Stream.generate(()->"Hello").limit(5).forEach(k -> System.out.println(k));
        Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)).limit(5).forEach(System.out::println);
//        System.out.println("-------------------");


        // stream()、map()、forEach()
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "Hello", "World");
        list.forEach(System.out::println);
        Stream<Stream<String>> out = list.stream().map(w -> codePoints(w));
        codePoints("World").forEach(System.out::println);
        System.out.println("-------------------");

        /*
        takeWhile()、dropWhile()
            takeWhile():产生一个流,流中的元素满足传入的谓词条件
            dropWhile():产生一个流,流的元素是当前流中排除不满足谓词条件的元素之外的所有元素
         */
        Stream<String> s0 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        Stream<String> s1 = Stream.of("Forlogen", "Kobe", "James", "Bill");
        s0.takeWhile(ss -> ss.startsWith("F")).forEach(System.out::println); // Forlogen
        s1.dropWhile(ss -> ss.startsWith("F")).forEach(System.out::println); // Kobe  James  Bill
        System.out.println("-------------------");

        /*
        Stream<T> distinct ():返回一个流,元素为原来流中的元素剔除重复元素后的结果
         */
        Stream<String> s2 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forlogen","Forlogen");
        s2.distinct().forEach(System.out::println);
        System.out.println("-------------------"); // Forlogen  Kobe  James  Bill

        /*
        Stream<T> sorted ():按照自然序就行排列,如String按照字典序排序,数值型按照大小排序
                            排序的元素要实现Comparable接口
        Stream<T> sorted (Comparator<? super T> comparator): 根据传入的Comparator指定的顺序就行排列,返回一个新的流
         */
        Stream<String> s3 = Stream.of("Forlogen", "Kobe", "James", "Bill");
        s3.sorted().forEach(System.out::println);
        System.out.println("-------------------");  // Bill Forlogen James  Kobe
        Stream<Integer> s4 = Stream.of(3, 1, 10, 7, 4);
        s4.sorted().forEach(System.out::println);  // 1 3 4 7 10
        System.out.println("-------------------");
        Stream<Integer> s5 = Stream.of(3, 1, 10, 7, 4);
        s5.sorted(Comparator.comparing(Integer::intValue).reversed()).forEach(System.out::println); // 10 7 4 3 1
        System.out.println("-------------------");

        /*
        Optional<T>    max(Comparator<? super T> comparator):返回按指定排序规则排序后流中的最小元素
        Optional<T>    min(Comparator<? super T> comparator):返回按指定排序规则排序后流中的最大元素
         */
        Stream<Integer> s6 = Stream.of(3, 1, 10, 7, 4);
        Optional<Integer> min = s6.min(Comparator.comparing(Integer::intValue));
        System.out.println(min.get());  // 1
        System.out.println("-------------------");
        Stream<Integer> s7 = Stream.of(3, 1, 10, 7, 4);
        Optional<Integer> max = s7.max(Comparator.comparing(Integer::intValue));
        System.out.println(max.get());  // 10
        System.out.println("-------------------");

        /*
        Optional<T>    findFirst():返回产生这个流的第一个元素
        Optional<T>    findAny():返回产生这个流的任意一个元素
        如果流为空,则返回空的Optional对象
         */
        Stream<String> s8 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s8.takeWhile(ss -> ss.startsWith("F")).findFirst().get()); // Forlogen
        System.out.println("-------------------");
        Stream<String> s9 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s9.takeWhile(ss -> ss.startsWith("F")).findAny().get()); // Forlogen
        System.out.println("-------------------");

        /*
        boolean    anyMatch (Predicate<? super T> predicate): 流中存在匹配条件的元素时返回true
        boolean    allMatch (Predicate<? super T> predicate): 流中任意一个元素都匹配条件时返回true
        boolean    noneMatch (Predicate<? super T> predicate): 流中没有一个元素匹配条件时返回true
         */
        Stream<String> s10 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        Stream<String> s11 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        Stream<String> s12 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(s10.anyMatch(s -> s.startsWith("F"))); // true
        System.out.println(s11.allMatch(s -> s.startsWith("F"))); // false
        System.out.println(s12.noneMatch(s -> s.startsWith("F"))); // false
        System.out.println("-------------------");

        /*
        Object[] oArray(): 返回对象数组
        <A> A[]    toArray (IntFunction<A[]> generator):返回A类型的数组
         */
        Stream<String> s13 = Stream.of("Forlogen", "Kobe", "James", "Bill", "Forever");
        System.out.println(Arrays.toString(s13.takeWhile(s -> s.startsWith("F")).toArray())); // [Forlogen]
        Stream<String> s14 = Stream.of("Forever", "Kobe", "James", "Bill");
        System.out.println(Arrays.toString(s14.takeWhile(s -> s.length() > 4).toArray(String[]::new)));  // [Forever]
        System.out.println("-------------------");

        /*
        static <T> Stream<T> ofNullable(T t):返回含单个元素的流
         */
        Stream<Object> s15 = Stream.ofNullable(10);
        s15.forEach(System.out::println);  // 10
        System.out.println("-------------------");

        /*
        Optional<T>    reduce (BinaryOperator<T> accumulator):用给定的accumulator产生流中元素的累积总和
         */
        Stream<Integer> s16 = Stream.of(3, 1, 10, 7, 4);
        System.out.println(s16.reduce(Integer::sum).get()); // 25
        System.out.println("-------------------");

        /*
        void forEachOrdered(Consumer<? super T> action): 为该流的每个元素执行一个操作,如果该流具有已定义的相遇顺序,则按照该流的相遇顺序执行。
         */
        Stream<Integer> s17 = Stream.of(3, 1, 10, 7, 4);
        s17.forEach(System.out::println);
        System.out.println("-------------------");
        Stream<Integer> s18 = Stream.of(3, 1, 10, 7, 4);
        s18.forEachOrdered(System.out::println);
    }

    public static Stream<String> codePoints(String s){
        ArrayList<String> list = new ArrayList<>();
        int i = 0;
        while (i < s.length()){
            int j = s.offsetByCodePoints(i, 1);
            list.add(s.substring(i, j));
            i = j;
        }
        return list.stream();
    }
}