• Java 8 新特性——Lambda 表达式(2)


     一、Java Stream API

            Java Stream函数式编程接口最初在Java 8中引入,并且与 lambda 一起成为Java开发里程碑式的功能特性,它极大的方便了开放人员处理集合类数据的效率。

            Java Stream就是一个数据流经的管道,并且在管道中对数据进行操作,然后流入下一个管道。有学过linux 管道的同学应该会很容易就理解。在没有Java Stram之前,对于集合类的操作,更多的是通过for循环。大家从后文中就能看出Java Stream相对于for 循环更加简洁、易用、快捷。

            管道的功能包括:Filter(过滤)、Map(映射)、sort(排序)等,集合数据通过Java Stream管道处理之后,转化为另一组集合或数据输出。

    二、Stream API代替for循环

    先来看一个例子:

    1. List nameStrs = Arrays.asList("Monkey", "Lion", "Giraffe","Lemur");
    2. List list = nameStrs.stream()
    3. .filter(s -> s.startsWith("L"))
    4. .map(String::toUpperCase)
    5. .sorted()
    6. .collect(toList());
    7. System.out.println(list);
    • 首先,我们使用Stream()函数,将一个List转换为管道流。
    • 调用filter函数过滤数组元素,过滤方法使用lambda表达式,以L开头的元素返回true被保留,其他的List元素被过滤掉。
    • 然后调用Map函数对管道流中每个元素进行处理,字母全部转换为大写。
    • 然后调用sort函数,对管道流中数据进行排序。默认情况下,使用 sorted() 方法进行排序时,会按照自然顺序进行排序。对于字符串来说,自然顺序即按照字母的升序进行排序。sorted() 方法对转换为大写形式后的字符串进行排序。因为大写字母的 Unicode 值小于相应的小写字母,所以在排序时会先排列大写字母,然后是小写字母。
    • 最后调用collect函数toList,将管道流转换为List返回。

           最终的输出结果是:[LEMUR, LION]。

            当然如果想要根据其他规则进行排序,可以使用 sorted(Comparator) 方法,并提供一个自定义比较器来指定排序的规则。比如可以使用 sorted((str1, str2) -> str1.length() - str2.length()) 来按字符串长度进行排序。

    1. import java.util.Comparator;
    2. public class StringLengthComparator implements Comparator {
    3. @Override
    4. public int compare(String str1, String str2) {
    5. return str1.length() - str2.length();
    6. }
    7. }

            创建了一个名为 StringLengthComparator 的类,它实现了 Comparator 接口。这个接口要求我们实现 compare 方法来定义元素之间的排序规则。

            在 compare 方法中,使用 str1.length() - str2.length() 来比较两个字符串的长度。如果 str1 的长度小于 str2 的长度,返回一个负值。如果 str1 的长度大于 str2 的长度,返回一个正值。如果 str1str2 的长度相等,返回 0。通过传递 new StringLengthComparator()sorted() 方法,可以按照字符串长度进行排序。

    1. List sortedList = nameStrs.stream()
    2. .filter(s -> s.startsWith("L"))
    3. .map(String::toUpperCase)
    4. .sorted(new StringLengthComparator())
    5. .collect(Collectors.toList());
    6. System.out.println(sortedList);

             当然,使用Java 8之前的方法来实现对一个string列表进行排序:

    1. List names = Arrays.asList("peter", "anna", "mike", "xenia");
    2. Collections.sort(names, new Comparator() {
    3. @Override
    4. public int compare(String a, String b) {
    5. return b.compareTo(a);
    6. }
    7. });

            使用 Lambda 表达式后的效果是:

    1. Collections.sort(names, (String a, String b) -> {
    2. return b.compareTo(a);
    3. });
    4. // 只有一条逻辑语句,可以省略大括号
    5. Collections.sort(names, (String a, String b) -> b.compareTo(a));
    6. // 可以省略入参类型
    7. Collections.sort(names, (a, b) -> b.compareTo(a));

    三、将数组转换为管道流

            使用Stream.of()方法,将数组转换为管道流。

    1. String[] array = {"Monkey", "Lion", "Giraffe", "Lemur"};
    2. Stream nameStrs2 = Stream.of(array);
    3. Stream nameStrs3 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");

    四、将集合类对象转换为管道流

            通过调用集合类的stream()方法,将集合类对象转换为管道流。

    1. List list = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur");
    2. Stream streamFromList = list.stream();
    3. Set set = new HashSet<>(list);
    4. Stream streamFromSet = set.stream();

    五、将文本文件转换为管道流

            通过Files.lines方法将文本文件转换为管道流,Paths.get()方法作用就是获取文件,是Java NIO的API也就是说:我们可以很方便的使用Java Stream加载文本文件,然后逐行的对文件内容进行处理。

    Stream lines = Files.lines(Paths.get("file.txt"));
    

    六、转换成流后面的操作

            一旦将数组或一组值转换为流,你就可以使用流的各种操作方法对其进行处理和操作。下面是一些示例操作:

    ①、遍历流中的元素:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. nameStrs2.forEach(System.out::println);

    ②、过滤流中的元素:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. Stream filteredStream = nameStrs2.filter(s -> s.startsWith("L"));

    ③、对流中的元素进行转换:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. Stream upperCaseStream = nameStrs2.map(String::toUpperCase);

     ④、对流中的元素进行排序:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. Stream sortedStream = nameStrs2.sorted();

    ⑤、对流中的元素进行聚合操作:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. Optional longestString = nameStrs2.max(Comparator.comparingInt(String::length));

     ⑥、收集流中的元素到集合中:

    1. Stream nameStrs2 = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");
    2. List stringList = nameStrs2.collect(Collectors.toList());
  • 相关阅读:
    矩阵的概念
    15 个实用的 Linux find 命令示例
    Got a packet bigger than ‘max_allowed_packet‘ bytes_navicat_heidisql工具导入报错
    【T+】余额表联查明细账,提示未将对象引用设置到对象的实例;参数格式错误,solutionID不能为空。
    FS4061A(5V USB输入、双节锂电池串联应用、5v升压充电8.4v管理IC
    ELK极简上手
    【Java 进阶篇】Java XML快速入门:理解、解析和生成XML
    3.1 面向对象的思想
    防雷接地+防雷工程施工综合方案
    数据结构之线性表中的单链表【详解】
  • 原文地址:https://blog.csdn.net/weixin_49171365/article/details/129753901