说明
本文内容来自 【Java8 In Action】 一书
四种方法引用类型
类型 | 示例 |
---|---|
引用静态方法 | ContainingClass::staticMethodName |
引用某个对象的实例方法 | containingObject::instanceMethodName |
引用某个类型的任意对象的实例方法 | ContainingType::methodName |
引用构造方法 | ClassName::new |
筛选和切片:
去重:
截取:
跳过元素:
对流中每个元素应用函数:
流的扁平化(合并流):
给 定 单 词 列 表["Hello","World"] ,返回列表 ["H","e","l", "o","W","r","d"] 。
使用 flatmap 合并流:
判断是否至少匹配一个元素:
if(menu.stream().anyMatch(Dish::isVegetarian())) {
// do something.......
}
anyMatch 返回一个 boolean 值
判断是否匹配所有元素:
if(menu.stream().allMatch(Dish::isVegetarian())) {
// do something.......
}
allMatch 返回一个 boolean 值
查找第一个元素:
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstSquareDivisibleByThree =
someNumbers.stream()
.map(x -> x * x)
.filter(x -> x % 3 == 0)
.findFirst();
归约操作
元素求和:
// 传统写法
int sum = 0;
for (int x : numbers) {
sum += x;
}
// Stream 写法
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> sum = numbers.stream().reduce((a, b) -> (a + b));
最大值和最小值:
Optional<Integer> max = numbers.stream().reduce(Integer::max);
Optional<Integer> min = numbers.stream().reduce(Integer::min);
数值流:
int calories = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);
它有一个暗含的装箱成本。每个 Integer 都必须拆箱成一个原始类型,再进行求和。
Java8 中引入了三个原始类型流接口: IntStream 、 DoubleStream 和LongStream ,分别将流中的元素特化为 int 、 long 和 double ,从而避免了暗含的装箱成本。
1、映射到数值流
menu.stream().mapToInt(xxxx).sum();
2、映射到对象流
IntStream intStream = menu.stream().mapToInt(xxxx);
Stream<Integer> stream = intStream.boxed();
数值范围:
IntStream evenNumbers = IntStream.rangeClosed(1, 100)
.filter(n -> n % 2 == 0);
range:不含结束值
rangeClosed:包含结束值
创建流的几种方式
1、由值创建流:
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
2、由数组创建流:
int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();
3、由函数生成流:
Stream API提供了两个静态方法来从函数生成流: Stream.iterate 和 Stream.generate 。这两个操作可以创建所谓的无限流:不像从固定集合创建的流那样有固定大小的流。由 iterate和 generate 产生的流会用给定的函数按需创建值,因此可以无穷无尽地计算下去!一般来说,应该使用 limit(n) 来对这种流加以限制,以避免打印无穷多个值。
Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);