使用流

1.筛选各异元素
流还支持一个叫作distinct的方法,它会返回一个元素各异(根据流所生成元素的 hashCode和equals方法实现)的流
2.截断流
流支持limit(n)方法,该方法会返回一个不超过给定长度的流。所需的长度作为参数传递 给limit。如果流是有序的,则最多会返回前n个元素。
3.跳过元素
流还支持skip(n)方法,返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一 个空流。请注意,limit(n)和skip(n)是互补的。
4.Arrays.stream()方法可以接受一个数组并产生一个流
例如:
String[] arrayOfWords = {"Goodbye", "World"}; Stream<String> streamOfwords = Arrays.stream(arrayOfWords);
5.flatMap的使用
map(w -> w.split(""))
flatmap(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流
6.查找和匹配
(1)检查谓词是否至少匹配一个元素
if(menu.stream().anyMatch(Dish::isVegetarian)){
System.out.println("The.....");}
anyMatch方法返回一个boolean,为终端操作
(2)检查谓词是否匹配所有元素allMatch
(3和allMatch相对的是noneMatch。它可以确保流中没有任何元素与给定的谓词匹配
(4)查找元素
findAny方法将返回当前流中的任意元素
例如:
Optional<Dish> dish = menu.stream()
.filter(Dish::isVegetarian) .findAny();
Optional<T>类(java.util.Optional)是一个容器类,代表一个值存在或不存在。在 上面的代码中,findAny可能什么元素都没找到。
isPresent()将在Optional包含值的时候返回true, 否则返回false。
 ifPresent(Consumer<T> block)会在值存在的时候执行给定的代码块。
 T get()会在值存在时返回值,否则抛出一个NoSuchElement异常。
 T orElse(T other)会在值存在时返回值,否则返回一个默认值。
(5)查找第一个元素findFirst()
7.归约
(1)求和
reduce操作是如何作用于一个流的:Lambda反复结合每个元素,直到流被归约成一个值。
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
int sum = numbers.stream().reduce(0,Integer::sum);
无初始值:
Option<Integer> sum = numbers.stream().reduce((a,b)->(a+b));
reduce接受两个参数:
 一个初始值,这里是0;
 一个BinaryOperator<T>来将两个元素结合起来产生一个新值,这里我们用的是
lambda (a, b) -> a + b。
(2)最大值和最小值
最大值:
Optional<Integer> max = numbers.stream().reduce(Integer::max);
最小值:
Optional<Integer> min = numbers.stream().reduce(Integer::min);
你当然也可以写成Lambda (x, y) -> x < y ? x :y
(3)计算流中元素个数
内置count方法可用来计算流中元素 的个数:
long count = menu.stream().count();
8.数据流
原始类型流特化
IntStream、DoubleStream和 LongStream,分别将流中的元素特化为int、long和double,从而避免了暗含的装箱成本
(1)映射到数据流
常用方法是mapToInt、mapToDouble和mapToLong。这些方法和前面说的map方法的工作方式一样,只是它们返回的是一个特化流,而不是Stream<T>
int calories = menu.stream()
.mapToInt(Dish::getCalories)
.sum();
(2)转换回对象流
要把原始流转换成一般流(每个int都会装箱成一个 Integer),可以使用boxed方法,如下所示:
IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream<Integer> stream = intStream.boxed();
(3)默认值OptionalInt
Optional类,这是一个可以表示值存在或不存在的容器。Optional可以用 Integer、String等参考类型来参数化。对于三种原始流特化,也分别有一个Optional原始类 型特化版本:OptionalInt、OptionalDouble和OptionalLong。
例如,要找到IntStream中的最大元素,可以调用max方法,它会返回一个OptionalInt:
OptionalInt maxCalories = menu.stream() .mapToInt(Dish::getCalories).max();
现在,如果没有最大值的话,你就可以显式处理OptionalInt去定义一个默认值了:
int max = maxCalories.orElse(1);
(4)数值范围
IntStream和LongStream的静态方法,帮助生成这种范围: range和rangeClosed。这两个方法都是第一个参数接受起始值,第二个参数接受结束值。但 range是不包含结束值的,而rangeClosed则包含结束值

9.构建流
(1)由值创建流
使用静态方法Stream.of通过显式值创建一个流。它可以接受任意数量的参数。例 如,以下代码直接使用Stream.of创建了一个字符串流。然后,你可以将字符串转换为大写,再 一个个打印出来:
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); stream.map(String::toUpperCase).forEach(System.out::println);
你可以使用empty得到一个空流,如下所示: Stream<String> emptyStream = Stream.empty();
(2)由数组创建流
使用静态方法Arrays.stream从数组创建一个流。它接受一个数组作为参数。例如,
你可以将一个原始类型int的数组转换成一个IntStream,如下所示:
int[] numbers = {2, 3, 5, 7, 11, 13}; int sum = Arrays.stream(numbers).sum();
(3)由函数生成流:创建无限流
Stream.iterate和Stream.generate。 这两个操作可以创建所谓的无限流
1. 迭代 我们先来看一个iterate的简单例子,然后再解释:
Stream.iterate(0, n -> n + 2)
.limit(10) .forEach(System.out::println);
2. 生成
与iterate方法类似,generate方法也可让你按需生成一个无限流。但generate不是依次 对每个新生成的值应用函数的。它接受一个Supplier<T>类型的Lambda提供新的值。我们先来看一个简单的用法:
Stream.generate(Math::random)
.limit(5) .forEach(System.out::println);
通过实现IntSupplier接口中定义的getAsInt方法显式传递 一个对象(虽然这看起来是无缘无故地绕圈子,也请你耐心看):
IntStream twos = IntStream.generate(new IntSupplier(){ public int getAsInt(){
return 2; }
});
总结:
此外,流可以透明地并行化。以下是你应从本章中学到的关键概念。
 Streams API可以表达复杂的数据处理查询。常用的流操作总结在表5-1中。
 你可以使用filter、distinct、skip和limit对流做筛选和切片。
 你可以使用map和flatMap提取或转换流中的元素。 你可以使用findFirst和findAny方法查找流中的元素。你可以用allMatch、
noneMatch和anyMatch方法让流匹配给定的谓词。
  •   这些方法都利用了短路:找到结果就立即停止计算;没有必要处理整个流。
  •   你可以利用reduce方法将流中所有的元素迭代合并成一个结果,例如求和或查找最大
元素。
  •   filter和map等操作是无状态的,它们并不存储任何状态。reduce等操作要存储状态才
能计算出一个值。sorted和distinct等操作也要存储状态,因为它们需要把流中的所
有元素缓存起来才能返回一个新的流。这种操作称为有状态操作。
  •   流有三种基本的原始类型特化:IntStream、DoubleStream和LongStream。它们的操
作也有相应的特化。
  •   流不仅可以从集合创建,也可从值、数组、文件以及iterate与generate等特定方法
创建。
  •   无限流是没有固定大小的流。

猜你喜欢

转载自blog.csdn.net/lyx_win/article/details/80559209
今日推荐