构建流


import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.IntSupplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;


/**
 * 构建流
 */
public class StreamDemo{
    public static void main(String[] args){
        //有值创建流
        Stream<String> stream = Stream.of("Hello","World");
        stream.map(String::toUpperCase).forEach(System.out::println);

        //得到一个空流
        Stream<String> emptyStream = Stream.empty();

        //数组创建流
        int[] numbers = {1, 2, 3, 4, 5};
        int sum = Arrays.stream(numbers).sum();
        System.out.println(sum);

        //由文件生成流
        //Java中用于处理文件等I/O操作的NIO API(非阻塞 I/O)
        long uniqueWords = 0;
        try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){//流会自动 关闭
            uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))//生成单词流
                    .distinct()//删除重复项
                    .peek(System.out::println)//窥视
                    .count();//数一数有多少个不相同的单词
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(uniqueWords);

        //由函数生成流:创建无限流
        //Stream API提供了两个静态方法来从函数生成流:Stream.iterate和Stream.generate。 这两个操作可以创建所谓的无限流
        //使用limit(n)来对这种流加以限制,以避免打印无穷多个值

        //迭代
        //生成了一个所有正偶数的流
        Stream.iterate(0,n->n+2)//iterate方法接受一个初始值(在这里是0)
                .limit(10)
                .forEach(System.out::println);//调用forEach终端操作来消费流,并分别打印每个元素

        //斐波纳契元组序列
        Stream.iterate(new int[]{0, 1},t->new int[]{t[1],t[0]+t[1]})//iterate的方法则是纯粹不变的:它没有修改现有状态
                .limit(20)
                .map(t->t[0])
                .forEach(System.out::println);//0, 1, 1, 2, 3, 5, 8, 13, 21, 34...

        //generate方法也可让你按需生成一个无限流,但generate不是依次 对每个新生成的值应用函数的
        Stream.generate(Math::random)
                .limit(5)
                .forEach(System.out::println);

        //Lambda允许你创建函数式接口的实例,只要直接内联提供方法的实 现就可以
        //generate方法将使用给定的供应源,并反复调用getAsInt方法,而这个方法总是返回2
        IntStream twos = IntStream.generate(new IntSupplier() {
            @Override
            public int getAsInt() {
                return 2;
            }
        });

        //generate实现斐波纳契数列
        IntSupplier fib = new IntSupplier() {//此对象有可变的状态
            private int previous = 0;
            private int current = 1;
            @Override
            public int getAsInt() {//getAsInt在调用时会改变对象的状态
                int oldPrevious = this.previous;
                int nextValue = this.previous + this.current;
                this.previous = this.current;
                this.current = nextValue;
                return oldPrevious;
            }
        };
        IntStream.generate(fib).limit(10).forEach(System.out::println);
        //终端操作(这里是forEach)将永远计算下去。同样,你不能对无限流 做排序或归约,因为所有元素都需要处理
        //应该始终采用不变的方法,以便并行处理流,并保持结果正确
    }
}
posted @ 2020-04-07 10:26  fly_bk  阅读(81)  评论(0编辑  收藏  举报