4.0 KiB
4.0 KiB
筛选与切片
- 用谓词筛选filter
- 筛选各异的元素distinct(去重)
- 截短流limit(n)
- 跳过元素skip(n)
映射
- 对流中每一个元素应用函数map
- 流的扁平化
字符->字节
使用flatmap,把一个流中的每个值都转换为另一个流,再把所有的流都连接起来
List<String> uniqueCharacters = words.stream() .map(w -> w.split("")) .flatmap(Array::stream) // 将各个生成流扁平化为单个流 .distinct() .collect(Collections.toList());
查找和匹配
- 检查谓词是否至少匹配一个元素 anyMatch,返回boolean,终端操作
- 检查谓词是否匹配所有元素 allMatch,
- 检查谓词是否与任何元素不匹配 noneMatch
- 查找元素 findAny,返回流中任意元素
- 查找第一个元素 findFirst
规约
- 元素求和 reduce,
int sum = numbers.stream().reduce(0, (a, b) -> a+b);
int product = numbers.stream().reduce(1, (a, b) -> a*b);
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> sum = numbers.stream().reduce((a, b) -> a+b);
0为初始值,
一个BinaryOperation<T>将两个元素结合起来产生一个新值
**无初始值**时,reduce返回一个Optional对象
- 最大和最小值 利用 reduce 计算,
Optional<Integer> max=numbers.Stream (). Reduce (Integer::max);
Optional<Integer> min=numbers.Stream (). Reduce (Integer::min);
- 计算个数
int count = menu.stream().map(d-> 1).reduce(0, (a, b)-> a+b);
long count = menu.stream().count()
有状态操作
Sort 和 dsitinct 等操作一开始和 map 和 filter 差不多,但是排序和删除重复项都需要之前的历史,这种状态称为有状态操作,reduce,sum,max 保存了一个内部状态,但这个是有界的,map,filter 会获取每一个元素,并在输出流中得到一个或 0 个结果,这种是无状态的
数值流
在求和时包装类型在进行数据计算时有一个装箱成本,流中的元素都是 Integer 类型的
原始类型流特化
IntStream、DoubleStream、LongStream
- 映射到数值流 mapToInt、mapToDouble、mapToLong 可以返回一个特化流
- 转换为对象流
使用 boxed 方法
intStream.boxed() - 默认值 Optional 对于三种特化流,有 OptionalInt、OptionalDouble、OptionalLong 对应,
OptionalInt maxCalories=menu.stream().mapToInt(Dish::getCalories).max();
// 如果没有最大值,显示提供一个最大值
int max = maxCalories.orElse(1);
数值范围
生成特定数值范围的流
IntStream evenNumbers = IntStream.rangClosed(1, 100).filter(n -> n % 2 == 0);
System.out.println(evenNumbers.count());
勾股数
Stream<int[]> pythagoreanTriples = IntStream.rangClosed(1, 100).boxed()
.faltMap(a ->
IntStream.rangClosed(a, 100)
.filter(b -> Math.sqrt((a*a + b*b) % 1 == 0))
.mapToObj(b ->
new int[]{a, b, (int)Math.sqrt(a*a + b*b)})
);
// 先生成所有三元数,再筛选符合条件的
Stream<Double[]> pythagoreanTriples2 = IntStream.rangClosed(1, 100).boxed()
.faltMap(a ->
IntStream.rangClosed(a, 100)
.filter(b -> Math.sqrt((a*a + b*b) % 1 == 0))
.mapToObj(b ->
new Double[]{a, b, (int)Math.sqrt(a*a + b*b)})
.filter(t -> t[2] % 1 == 0)
);
构建流
- 由值构建, 使用 Stream.of
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
// 获取一个空流
Stream<String> emptyStream = Stream.empty
-
由数组构建, 使用 Array.stream 从数组创建
-
由文件, 使用 File.lines 得到一个流
-
由函数创建, Stream.iterate 和 Stream.generate, 这两个操作可以创建所谓的无限流
Stream.iterate(0, n-> n+2)
.limit(10)
.forEach(System.out::println);
Stream.generate(Math::random)
.limit(5)
.forEach(System.out::println)