Fellow Travellers

Java 8 之Lambda表达式Stream使用

万世威
字数统计: 674阅读时长: 3 min
2018/10/23 Share

Lambda表达式Stream使用

==来自 【 Java8 In Action】 一书==

四种方法引用类型

类型 示例
引用静态方法 ContainingClass::staticMethodName
引用某个对象的实例方法 containingObject::instanceMethodName
引用某个类型的任意对象的实例方法 ContainingType::methodName
引用构造方法 ClassName::new

筛选和切片:

去重:

截取:

跳过元素:

对流中每个元素应用函数:

流的扁平化(合并流):

给 定 单 词 列 表[“Hello”,”World”] ,返回列表 [“H”,”e”,”l”, “o”,”W”,”r”,”d”] 。

使用 flatmap 合并流

判断是否至少匹配一个元素:

1
2
3
4
if(menu.stream().anyMatch(Dish::isVegetarian())) {
// do something.......
}
anyMatch 返回一个 boolean 值

判断是否匹配所有元素:

1
2
3
4
if(menu.stream().allMatch(Dish::isVegetarian())) {
// do something.......
}
allMatch 返回一个 boolean 值

查找第一个元素:

1
2
3
4
5
6
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();

归约操作

元素求和:

1
2
3
4
5
6
7
8
9
10
// 传统写法
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));

最大值和最小值:

1
2
Optional<Integer> max = numbers.stream().reduce(Integer::max);
Optional<Integer> min = numbers.stream().reduce(Integer::min);

数值流:

1
int calories = menu.stream().map(Dish::getCalories).reduce(0, Integer::sum);

它有一个暗含的装箱成本。每个 Integer 都必须拆箱成一个原始类型,再进行求和。

Java8 中引入了三个原始类型流接口: IntStream 、 DoubleStream 和LongStream ,分别将流中的元素特化为 int 、 long 和 double ,从而避免了暗含的装箱成本。

1、映射到数值流

1
menu.stream().mapToInt(xxxx).sum();

2、映射到对象流

1
2
IntStream intStream = menu.stream().mapToInt(xxxx);
Stream<Integer> stream = intStream.boxed();

数值范围:

1
2
3
4
IntStream evenNumbers = IntStream.rangeClosed(1, 100)
.filter(n -> n % 2 == 0);
range:不含结束值
rangeClosed:包含结束值

创建流的几种方式

1、由值创建流:

1
2
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);

2、由数组创建流:

1
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) 来对这种流加以限制,以避免打印无穷多个值。

1
2
3
Stream.iterate(0, n -> n + 2)
.limit(10)
.forEach(System.out::println);
1
2
3
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println);
CATALOG
  1. 1. Lambda表达式Stream使用
    1. 1.1. 四种方法引用类型
    2. 1.2. 筛选和切片:
    3. 1.3. 去重:
    4. 1.4. 截取:
    5. 1.5. 跳过元素:
    6. 1.6. 对流中每个元素应用函数:
    7. 1.7. 流的扁平化(合并流):
    8. 1.8. 判断是否至少匹配一个元素:
    9. 1.9. 判断是否匹配所有元素:
    10. 1.10. 查找第一个元素:
  2. 2. 归约操作
    1. 2.1. 元素求和:
    2. 2.2. 最大值和最小值:
    3. 2.3. 数值流:
      1. 2.3.1. 1、映射到数值流
      2. 2.3.2. 2、映射到对象流
    4. 2.4. 数值范围:
  3. 3. 创建流的几种方式