1 流的介绍
使用流,就是说明想要完成什么任务,而不是说明如何去实现它。将操作的调度留给具体的实现去解决。如,我们想要计算某个属性的平均值,我们就通过指定数据源和该属性完成,比如,一箱苹果的斤数平均值,我们可以通过指定苹果所在集合与斤数对应的属性。然后流库就可以对数据进行优化,例如,使用多线程来计算总和与个数,并将结果合并。流主要用来以做什么而非怎么做来处理集合。
从迭代到流的操作举例:
String contents = new String(Files.readAllBytes(
Paths.get("C:\\Users\\x1c\\Downloads\\corejava\\corejava\\v2ch01\\streams\\CountLongWords.java")), StandardCharsets.UTF_8);
List<String> words = Arrays.asList(contents.split("\\PL+"));
long count = 0;
for (String w : words)
{
if (w.length() > 12) count++;
}
System.out.println(count);
完全可以简化为
count = words.stream().filter(w -> w.length() > 12).count();
2 流的创建与使用
对于实现了Collection类的集合我们可以使用stream方法将集合转换为一个流。
对于数组,我们可以使用Stream.of方法。
Stream<String> words = Stream.of(contents.split("\\PL+"));
使用Array.stream(array,from,to)可以从数组中位于form(包括)和to(不包括)的元素中创建一个流。
使用Stream.empty创建一个不包含任何元素的流
Stream接口有两个用于创建无限流的静态方法,generate方法接受一个不包含任何引元的函数(Supplier<T>接口的对象)
Stream<String> echos = Stream.generate(() -> "Echo");
Stream.iterate可以产生一个无限序列,它接受一个种子值,以及一个函数,(UnaryOperation<T>),并且反复的将该函数应用到之前的结果上
Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE,
n -> n.add(BigInteger.ONE));
获取指定文件的行作为流
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8))
{
show("lines", lines);
}
3 流的转换
创建流后,需要对流进行筛选,选出所需要的流。使用流的转换会在原流的基础上产生一个新流,如前面的filter转换会产生一个与某种条件相匹配的流。filter的引元是Predicate<T>
map方法:如果我们想要按照某种方式来转换流中的值,可以使用map方法传递执行该转换的函数