Java8新特性之Lambda与Stream流

2022-05-12 10:58:54 浏览数 (1)

文章目录
  • 一、什么是Stream?
  • 二、Stream的创建方式
    • 1、用集合创建流
    • 2、用数组创建流
    • 3、使用Stream的静态方法
  • 三、Stream的使用
    • 1、筛选(filter)
    • 2、聚合(max/min/count)
    • 3、映射(map/flatMap)
    • 4、归约(reduce)
    • 5、排序(sorted)

一、什么是Stream?

   Java 8 API添加了一个新的抽象称为流Stream,stream是用于对集合迭代器的增强,使之能够更高效的完成聚合操作(筛选、排序、统计分组)或者大批量数据操作。    元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

1、Stream有几个特性:

  • stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
  • stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
  • stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

2、Stream可以由数组或集合创建,对流的操作分为两种:

  • 中间操作,每次返回一个新的流,可以有多个,所有中间操作都返回Stream(可以链接)。
  • 终端操作,每个流只能进行一次终端操作,终端操作结束后不返回流。终端操作会产生非流(无法链接)结果,例如原始值,集合或根本没有值。

3、在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() :为集合创建串行流。
  • parallelStream() :为集合创建并行流。

二、Stream的创建方式

1、用集合创建流

代码语言:javascript复制
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

2、用数组创建流

代码语言:javascript复制
int[] array = {1, 2, 3, 4, 5, 6};
IntStream stream = Arrays.stream(array);

3、使用Stream的静态方法

代码语言:javascript复制
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

Stream<Integer> stream = Stream.iterate(0, (x) -> x   3).limit(3);

Stream<Double> stream = Stream.generate(Math::random).limit(3);

三、Stream的使用

1、筛选(filter)

筛选,是按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。

(1)筛选出集合中大于5的元素,并形成新的集合,打印出来。

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
list.stream().filter(x -> x > 5).collect(Collectors.toList()).forEach(System.out::println);

2、聚合(max/min/count)

(1)获取String集合中最长的元素

代码语言:javascript复制
List<String> list = Arrays.asList("Java", "Python", "C  ", "C", "PHP");
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println("最长的字符串:"   max.get());

说明: Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

(2)获取Integer集合中的最小值

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> min = list.stream().min(Integer::compareTo);
System.out.println("自然排序的最小值:"   min.get());

(3)计算Integer集合中大于等于5的元素的个数

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
long count = list.stream().filter(x -> x > 5).count();
System.out.println("list中大于5的元素个数:"   count);

3、映射(map/flatMap)

  • map:转换流,将一种类型的流转换为另外一种流。
  • flatMap:拆解流,将流中每一个元素拆解成一个流。

(1)英文字符串数组的元素全部改为大写

代码语言:javascript复制
String[] strArr = {"Java", "Python", "C  ", "C", "PHP"};
Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList()).forEach(System.out::println);

(2)将两个字符数组合并成一个新的字符数组

代码语言:javascript复制
List<String> list = Arrays.asList("1,3,5,7,9", "2,4,6,8,10");
List<String> listNew = list.stream().flatMap(s -> {
    // 将每个元素转换成一个stream
    String[] split = s.split(",");
    Stream<String> s2 = Arrays.stream(split);
    return s2;
}).collect(Collectors.toList());
listNew.forEach(System.out::println);

4、归约(reduce)

   归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。 (1)求Integer集合的元素之和的三种方式

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> sum = list.stream().reduce((x, y) -> x   y); //方式1
Optional<Integer> sum2 = list.stream().reduce(Integer::sum); //方式2
Integer sum3 = list.stream().reduce(0, Integer::sum); //方式3
System.out.println("list求和:"   sum.get()   ","   sum2.get()   ","   sum3);

(2)求Integer集合的乘积和最大值

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
System.out.println("list求积:"   product.get());

(3)求Integer集合的最大值

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y); // 方式1
Integer max2 = list.stream().reduce(1, Integer::max); // 方式2
System.out.println("list求和:"   max.get()   ","   max2);

5、排序(sorted)

   sorted 方法用于对流进行排序。

代码语言:javascript复制
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
list.stream().sorted().forEach(System.out::println);

  倒排序

代码语言:javascript复制
String[] strArr = {"Java", "Python", "C  ", "C", "PHP"};
Arrays.stream(strArr).sorted(Comparator.comparing(String::length).reversed()).forEach(System.out::println);

0 人点赞