Java核心技术 Java SE 8的流库

1.从迭代到流的操作

在处理集合时,通常迭代遍历它的元素:

String contents = new String(Files.readAllBytes(Paths.get("alice30.txt")), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contents.split("\\PL+"));
long count = 0;
for (String w: words) {
   
    if (w.length() > 12) {
   
        count++;
    }
}

在使用流时:

long count = words.stream().filter(w -> w.length() > 12).count();

流的版本比循环版本要更易于阅读,因为不必扫描整个代码去查找过滤和计数操作,方法名就可以直接看到代码意欲何为。
循环需要非常详细地指定操作的顺序,而流却能够以其想要的任何方式来调度这些操作,只要结果正确即可。
将stream修改为parallelStream就可以让流库以并行方式来执行过滤和计数。
流遵循了做什么而非怎么做的原则。

流和集合的显著差异:
1.流并不存储其元素。这些元素可能存储在底层的集合中,或者是按需生成。
2.流的操作不会修改其数据源。
3.流的操作尽可能惰性执行的。这意味着直至需要其结果时,操作才会执行。

实例代码:stream会产生一个用于words列表的stream,filter方法会返回另一个流,其中只包含长度大于12的单词。count方法会将这个流化简为一个结果。

操作流时典型的三个阶段的操作管道:
1.创建一个流
2.指定将初始化流转换为其他流的中间操作,可能包含多个步骤
3.应用终止操作,从而产生结果。这个操作会强制执行之前的惰性操作。从此之后,这个流就再也不能用了。

2.流的创建

数组可以用静态的Stream.of方法:

Stream<String> words = Stream.of(contents.split("\\PL+"));

of方法具有可变长参数,因此可以具有任意数量引元的流:

Stream<String> song = Stream.of("gently", "down", "the", "stream");

使用Array.stream(arry, from, to)可以数组中位于from(包括)和to(不包括)的元素中创建一个流。
Stream.empty创建不包含任何元素的流。

Stream接口有两个用于创建无限流的静态方法。generate方法会接受一个不包含任何引元的函数(从技术上讲,是一个Supplier< T >接口的对象)。只需要一个流类型的值,该函数就会调用用以产生一个这样的值。获取一个常量值的流:

Stream<String> echos = Stream.generate(() -> "Echo"); // 无限个Echo

获取一个随机数的流:

Stream<Double> randoms = Stream.generate(Math::random);

为了产生无限序列(0 1 2 3)可以使用iterate方法。它会接受一个种子值,以及一个函数(OnaryOperation< T >),并反复将该函数应用到之前的结果:

Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));

第一个元素是种子BigInteger.ZERO,第二个是f(seed),第三个是f(f(seed))。

Patteran类有一个splitAsStream方法,它会按照某个正则表达式来分割一个CharSequence对象:

Stream<String> ws = Pattern.compile("\\PL+").splitAsStream(contents);  

静态的Files.lines方法会返回一个包含了文件所有行的Stream:

Stream<String> lines = Files.lines(Paths.get("alice30.txt"));  
public class CreatingStreams {
   
    public static <T> void show(String title, Stream<T> stream) {
   
        final int SIZE = 10;
        List<T> firstElements = stream.limit(SIZE + 1).collect(Collectors.toList());
        System.out.println(title + ": ");
        for (int i = 0; i < firstElements.size(); i++) {
   
            if (i > 0) {
   
                System.out.print(", ");
            }
            if (i < SIZE) {
   
                System.out.print(firstElements.get(i));
            } else {
   
                System.out.print("...");
            }
        }
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
   
        Path path = Paths.get("alice30.txt");
        String contents = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);

        Stream<String> words = Stream.of(contents.split("\\PL+"));
        show("words", words);
        Stream<String> song = Stream.of("gently", "down", "the", "stream");
        show("song", song);

        Stream<String> echos = Stream.generate((
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值