CoreJava卷2:高级特性 第1章 Java8的流库
一、从迭代到流
处理集合时,通常选择迭代遍历它的元素,并在每个元素上执行某项操作。
使用流进行操作可以不必扫描整个代码去进行查找、过滤、计数等操作,方法名就可以直接告诉我们其代码的含义。
- 流并不存储元素。这些元素可能存储在底层的集合中,或者是按需生成的。
- 流的操作不会改变数据源。
- 流的操作是尽可能惰性执行的。
二、流的创建
Collection接口的stream方法将任何集合转换为一个流。数组也可以使用静态方法Stream.of方法。
也可以使用Array.stream(array, from, to)用数组中的一部分元素来创建一个流。
若想创建一个不包含任何元素的流,可以用静态的Stream.empty方法。
也可以使用Stream接口中的静态generate方法创建无限流。
要产生迭代序列流,可以使用iterate方法,接受一个种子值以及一个函数。
如果要产生一个有限的流,需要添加一个谓词来描述迭代如何结束即可。
ofNullable方法会用一个对象来创建一个非常短的流。如果对象为null,那么这个流长度为0,否则长度为1,即只包含这个对象。
java.util.stream.Stream
1 | static <T> Stream<T> of(T... values); |
java.util.Spliterators
1 | static <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics) |
java.util.Arrays
1 | static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive); |
java.util.regex.Pattern
1 | Stream<String> splitAsStream(CharSqeuence input); |
java.nio.file.Files
1 | static Stream<String> lines(Path path); |
java.util.stream.StreamSupport
1 | static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel); |
java.lang.Iterable
1 | Spliterator<T> spliterator(); |
java.util.Scanner
1 | public Stream<String> tokens(); |
java.util.function.Supplier
1 | T get(); |
三、filter、map和flatMap方法
1 | Stream<T> filter(Predicate<? super T> predicate); |
四、抽取子流和组合流
调用stream.limit(n)会返回一个新的流,它在n个元素之后结束。
1 | Stream<Double> randoms = Stream.generate(Math::random).limit(100); |
会产生一个包含100个随机数的流。
调用stream.skip(n)丢弃前n个元素。
stream.takeWhile(predicate)调用会在谓词为真时获取流中的所有元素,然后停止。
dropWhile(predicate)正好相反,会在谓词为真时丢弃元素,并产生一个由第一个使该条件为假的字符开始构造的流。
Stream类的静态concat方法将两个流连接起来:
1 | Stream<String> combined = Stream.concat( |
五、其他的流转换
distinct方法会返回一个流,它的元素是从原有流中产生的,删除重复元素后产生的。
sorted方法会产生一个新的流,它的元素是流中按照顺序排列的元素。
peek方法会产生另一个流,它的元素与原来流中的元素相同,但是在每次获取一个元素时,都会调用一个函数。
1 | Stream<T> distinct(); |
六、简单约简
约简是一种终结操作,会将流约简为可以在程序中使用的非流值。
约简方法返回类型为Optional
Optional类型是一种表示缺少返回值的更好的方式.
1 | Optional<T> max(Comparator<? super T> comparator); |
七、Optional类型
Optional
7.1 获取Optional值
有效地使用Optional的关键是要使用这样的方法:它的值不存在的情况下会产生一个可替代物,而只有在值存在的情况下才会使用这个值。
1 | T orElse(T other); |
7.2 消费Optional值
1 | void ifPresent(Consumer<? super T> action); |
7.3 管道化Optional值
1 | <U> Optional<U> map(Function<? super T, ? extends U> mapper); |
7.4 不适合使用optional值的方式
1 | T get(); |
7.5 创建optional值
1 | static <T> Optional<T> of(T value); |
7.6 用flatMap构建Optional值的函数
1 | <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper); |
7.7 将optional转换为流
stream方法将Optional对象转换为Stream对象
八、收集结果
iterator方法会返回迭代器。
forEach方法将某个函数用于每个元素。
toArray方法获得由流元素构成的数组。
collect方法接收一个Collector接口的实例,将流元素收集到列表。
九、收集到映射表中
toMap、toUnmodifiableMap方法产生收集器,产生可修改和不可修改的映射表。keyMapper和valueMapper分别应用于每个收集到元素,从而在所产生的映射表中生成一个键、值项。
十、群组和分区
groupingBy、partitioningBy产生收集器。
十一、下游收集器
十二、约简操作
reduce从流中计算某个值,接收一个二元函数,并从前两个元素开始持续应用。
十三、基本数据流
IntStream、LongStream、DoubleStream、CharSequence、Random
十四、并行流
parallelStream方法获得集合的一个并行流。
据此,Java基础知识已基本覆盖,后续有查缺补漏仍会补上