Java的流库-2021-01-05

1.迭代与流的操作

对列表中的长单词计数
1.迭代操作
long count = 0;
for(String w : words){
    
    
    if.(w.length() > 12)
        count++;
}

2.使用流操作实现相同功能

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

使用流代替循环的好处: 流操作遵循“做什么而非怎么做原则”。
1.流版本比循环的版本更易于阅读,因为我们不必扫描整个代码去查找过滤和计数操作,方法名就可以直接告诉我们其代码意欲何为。
2.将stream()方法修改为parallelStream()方法就可以让流库以并行的方式执行过滤和计数。

流与集合的差异:
1.流并不存储其元素。(流使用的元素可能存储在底层的集合中,也可能是按照需求生成的)
2.流的操作不会修改数据源。(例如,filter()方法不会从新的流中移除元素,而是会生成一个新的流,其中不包括被过滤的掉的元素)
3.流的操作是尽可能惰性执行的。(意思是只有需要结果时,操作才会执行)

流的典型操作流程:
1.创建一个流。
2.指定将初始化流转化为其他流的中间操作,可能包含多个步骤。
3.应用终止操作,产生执行结果。

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class oneone {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //读文件将文件读到集合中
        String contents = new String(Files.readAllBytes(Paths.get("alice30.txt")), StandardCharsets.UTF_8);
        List<String> words = Arrays.asList(contents.split("//PL+"));

        long count = 0;
        //循环查找集合words中单词长度大于12的单词的数量。
        for(String w : words){
    
    
            if (w.length() > 12){
    
    
                count++;
            }
        }
        System.out.println(count);
        //单线程的流操作
        count = words.stream().filter(w -> w.length() > 12).count();
        System.out.println(count);
        //并发执行流的操作
        count = words.parallelStream().filter(w -> w.length() > 12).count();
        System.out.println(count);
    }
}
  • Stream filter(Predicate<? super T> p):产生一个流,其中包含当前流中满足P的所有元素。
  • long count():产生当前流中元素的数量。是流的一个终止操作。
  • default Stream stream():产生当前集合中所有元素的顺序流
  • default Stream parallelStream():产生当前集合中所有元素的并行流。

2.流的创建

 使用Collection接口的stream()方法将任何集合转化为一个流。
 使用静态的Stream.of()方法将数组转化为一个流。
 使用Array.stream(array, from, to)方法可以从数组中位于from(包括)和to(不包括)的元素中创建一个流。
 使用Stream.empty()方法创建一个不包含任何元素的流。
 使用Stream.generate(Supplier<T> P)方法或Stream.iterate(UnaryOperation<T> P)方法创建无限流。
 Pattern类有一个splitAsStream方法,它将按照某个正则表达式来分割一个CharSequence对象。
 静态的Files.lines方法返回一个包含了文件中所有行的Stream。
Stream<String> words = Stream.of(contents.split("\\PL+"));
Stream<String> words = Stream.of("gently", "down", "the");
Stream<String> words = Array.stream(contents, 1, 5);
Stream<String> slience = Stream.empty();
Stream<String> echos = Stream.generate(()-> "Echos");
Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
Stream<Stream> words = Pattern.compile("\\PL+").splitAsStream(contents);
try(Stream<String> lines = Files.lines(path))
{
    
    
     Process lines;
}
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class onetwo {
    
    
    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.println(", ");
            if (i < SIZE)
                System.out.println(firstElements.get(i));
            else
                System.out.println("...");
        }
        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> songs = Stream.of("gently", "down", "the", "stream");
        show("song", songs);
        //创建一个没有元素的流
        Stream<String> empty = Stream.empty();
        show("empty", empty);

        //创建一个某个字符串的无限流
        Stream<String> echos = Stream.generate(() ->"Echos");
        show("echos", echos);
        
        //创建一个随机数的无限流
        Stream<Double> randoms = Stream.generate(Math::random);
        show("randoms", randoms);
        
        //创建一个自增的无限流
        Stream<BigInteger> integerStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE));
        show("intergers", integerStream);
        
        //使用Pattern将文件转为一个流
        Stream<String> wordsAnotherWay = Pattern.compile("\\PL+").splitAsStream(contents);
        show("wprdsAnotherWay", wordsAnotherWay);
        
        //读文件将读到的每行转化为一个流
        try(Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)){
    
    
            show("lines", lines);
        }
    }
}
  1. static Stream of (T…values):产生一个元素为给定值的流。
  2. static Stream empty():产生一个空的流。
  3. static Stream generate(Suppliers):产生一个无限流,它的值是反复调用函数s而构建的。
  4. static Stream iterate(T seed, UnaryOperator f):产生一个无限流,它的元素包含种子、在种子上调用f产生的值、在前一个元素上调用f产生的值。
  5. static Stream stream(T[] array, int startInclusive, int endExclusive):产生一个流,它的元素是由数组中指定范围内的元素构成的。
  6. static splitAsStream(CharSequence input) :产生一个流,它的元素是输入中由该模式界定的部分。
    7.static Stream lines(Path path)
    8.static Stream lines(Path path, Charset cs):产生一个流,它的元素是指定文件中的行,该文件的字符集为UTF_8或者指定的字符集。

流操作的中间方法

1.filter()方法:将流转换为一个与某种条件匹配的新的流。
2.map()方法:按某种方式来转换流中的值。产生一个流,它包含将mapper应用于当前流中所有元素产生的结果。
3.flatMap()方法:产生一个流,它是通过将mapper应用于当前流中所有元素产生的结果连接到一起而获得的。

抽取子流和连接流的方法

1.limit(long maxSize)方法:产生一个流,其中包含了当前流中最初的maxSize个元素。
2.skip(long n)方法:它的元素是当前流中除了前n个元素之外的所有元素。
3.concat(Stream<?extends T> a, Stream<? extends T> b)方法:产生一个流,它的元素是a的元素后面跟着b的元素。

猜你喜欢

转载自blog.csdn.net/weixin_43222122/article/details/112215393