• Java之Stream流及方法引用的详细解析二


    2.6Stream流综合练习【应用】

    • 案例需求

      现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

      • 男演员只要名字为3个字的前三人

      • 女演员只要姓林的,并且不要第一个

      • 把过滤后的男演员姓名和女演员姓名合并到一起

      • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

      演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

    • 代码实现

      演员类

      1. public class Actor {
      2.    private String name;
      3.    public Actor(String name) {
      4.        this.name = name;
      5.   }
      6.    public String getName() {
      7.        return name;
      8.   }
      9.    public void setName(String name) {
      10.        this.name = name;
      11.   }
      12. }

      测试类

      1. public class StreamTest {
      2.    public static void main(String[] args) {
      3.        //创建集合
      4.        ArrayList manList = new ArrayList();
      5.        manList.add("周润发");
      6.        manList.add("成龙");
      7.        manList.add("刘德华");
      8.        manList.add("吴京");
      9.        manList.add("周星驰");
      10.        manList.add("李连杰");
      11.  
      12.        ArrayList womanList = new ArrayList();
      13.        womanList.add("林心如");
      14.        womanList.add("张曼玉");
      15.        womanList.add("林青霞");
      16.        womanList.add("柳岩");
      17.        womanList.add("林志玲");
      18.        womanList.add("王祖贤");
      19.  
      20.        //男演员只要名字为3个字的前三人
      21.        Stream manStream = manList.stream().filter(s -> s.length() == 3).limit(3);
      22.  
      23.        //女演员只要姓林的,并且不要第一个
      24.        Stream womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
      25.  
      26.        //把过滤后的男演员姓名和女演员姓名合并到一起
      27.        Stream stream = Stream.concat(manStream, womanStream);
      28.  
      29.     // 将流中的数据封装成Actor对象之后打印
      30.     stream.forEach(name -> {
      31.            Actor actor = new Actor(name);
      32.            System.out.println(actor);
      33.       });
      34.   }
      35. }

    3.方法引用

    3.1体验方法引用【理解】

    • 方法引用的出现原因

      在使用Lambda表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作

      那么考虑一种情况:如果我们在Lambda中所指定的操作方案,已经有地方存在相同方案,那是否还有必要再写重复逻辑呢?答案肯定是没有必要

      那我们又是如何使用已经存在的方案的呢?

      这就是我们要讲解的方法引用,我们是通过方法引用来使用已经存在的方案

    • 代码演示

      1. public interface Printable {
      2.    void printString(String s);
      3. }
      4. public class PrintableDemo {
      5.    public static void main(String[] args) {
      6.        //在主方法中调用usePrintable方法
      7. //       usePrintable((String s) -> {
      8. //           System.out.println(s);
      9. //       });
      10.    //Lambda简化写法
      11.        usePrintable(s -> System.out.println(s));
      12.        //方法引用
      13.        usePrintable(System.out::println);
      14.   }
      15.    private static void usePrintable(Printable p) {
      16.        p.printString("爱生活爱Java");
      17.   }
      18. }

    3.2方法引用符【理解】

    • 方法引用符

      :: 该符号为引用运算符,而它所在的表达式被称为方法引用

    • 推导与省略

      • 如果使用Lambda,那么根据“可推导就是可省略”的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导

      • 如果使用方法引用,也是同样可以根据上下文进行推导

      • 方法引用是Lambda的孪生兄弟

    3.3引用类方法【应用】

    引用类方法,其实就是引用类的静态方法

    • 格式

      类名::静态方法

    • 范例

      Integer::parseInt

      Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据

    • 练习描述

      • 定义一个接口(Converter),里面定义一个抽象方法 int convert(String s);

      • 定义一个测试类(ConverterDemo),在测试类中提供两个方法

        • 一个方法是:useConverter(Converter c)

        • 一个方法是主方法,在主方法中调用useConverter方法

    • 代码演示

      1. public interface Converter {
      2.    int convert(String s);
      3. }
      4. public class ConverterDemo {
      5.    public static void main(String[] args) {
      6. //Lambda写法
      7.        useConverter(s -> Integer.parseInt(s));
      8.        //引用类方法
      9.        useConverter(Integer::parseInt);
      10.   }
      11.    private static void useConverter(Converter c) {
      12.        int number = c.convert("666");
      13.        System.out.println(number);
      14.   }
      15. }

    • 使用说明

      Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数

    3.4引用对象的实例方法【应用】

    引用对象的实例方法,其实就引用类中的成员方法

    • 格式

      对象::成员方法

    • 范例

      "HelloWorld"::toUpperCase

      String类中的方法:public String toUpperCase() 将此String所有字符转换为大写

    • 练习描述

      • 定义一个类(PrintString),里面定义一个方法

        public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出

      • 定义一个接口(Printer),里面定义一个抽象方法

        void printUpperCase(String s)

      • 定义一个测试类(PrinterDemo),在测试类中提供两个方法

        • 一个方法是:usePrinter(Printer p)

        • 一个方法是主方法,在主方法中调用usePrinter方法

    • 代码演示

      1. public class PrintString {
      2.    //把字符串参数变成大写的数据,然后在控制台输出
      3.    public void printUpper(String s) {
      4.        String result = s.toUpperCase();
      5.        System.out.println(result);
      6.   }
      7. }
      8. public interface Printer {
      9.    void printUpperCase(String s);
      10. }
      11. public class PrinterDemo {
      12.    public static void main(String[] args) {
      13. //Lambda简化写法
      14.        usePrinter(s -> System.out.println(s.toUpperCase()));
      15.        //引用对象的实例方法
      16.        PrintString ps = new PrintString();
      17.        usePrinter(ps::printUpper);
      18.   }
      19.    private static void usePrinter(Printer p) {
      20.        p.printUpperCase("HelloWorld");
      21.   }
      22. }
    • 使用说明

      Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数

    3.5引用类的实例方法【应用】

    引用类的实例方法,其实就是引用类中的成员方法

    • 格式

      类名::成员方法

    • 范例

      String::substring

      public String substring(int beginIndex,int endIndex)

      从beginIndex开始到endIndex结束,截取字符串。返回一个子串,子串的长度为endIndex-beginIndex

    • 练习描述

      • 定义一个接口(MyString),里面定义一个抽象方法:

        String mySubString(String s,int x,int y);

      • 定义一个测试类(MyStringDemo),在测试类中提供两个方法

        • 一个方法是:useMyString(MyString my)

        • 一个方法是主方法,在主方法中调用useMyString方法

    • 代码演示

      1. public interface MyString {
      2.    String mySubString(String s,int x,int y);
      3. }
      4. public class MyStringDemo {
      5.    public static void main(String[] args) {
      6. //Lambda简化写法
      7.        useMyString((s,x,y) -> s.substring(x,y));
      8.        //引用类的实例方法
      9.        useMyString(String::substring);
      10.   }
      11.    private static void useMyString(MyString my) {
      12.        String s = my.mySubString("HelloWorld", 2, 5);
      13.        System.out.println(s);
      14.   }
      15. }

    • 使用说明

      Lambda表达式被类的实例方法替代的时候 ​ 第一个参数作为调用者 ​ 后面的参数全部传递给该方法作为参数

    3.6引用构造器【应用】

    引用构造器,其实就是引用构造方法

    • l格式

      类名::new

    • 范例

      Student::new

    • 练习描述

      • 定义一个类(Student),里面有两个成员变量(name,age)

        并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法

      • 定义一个接口(StudentBuilder),里面定义一个抽象方法

        Student build(String name,int age);

      • 定义一个测试类(StudentDemo),在测试类中提供两个方法

        • 一个方法是:useStudentBuilder(StudentBuilder s)

        • 一个方法是主方法,在主方法中调用useStudentBuilder方法

    • 代码演示

      1. public class Student {
      2.    private String name;
      3.    private int age;
      4.    public Student() {
      5.   }
      6.    public Student(String name, int age) {
      7.        this.name = name;
      8.        this.age = age;
      9.   }
      10.    public String getName() {
      11.        return name;
      12.   }
      13.    public void setName(String name) {
      14.        this.name = name;
      15.   }
      16.    public int getAge() {
      17.        return age;
      18.   }
      19.    public void setAge(int age) {
      20.        this.age = age;
      21.   }
      22. }
      23. public interface StudentBuilder {
      24.    Student build(String name,int age);
      25. }
      26. public class StudentDemo {
      27.    public static void main(String[] args) {
      28. //Lambda简化写法
      29.        useStudentBuilder((name,age) -> new Student(name,age));
      30.        //引用构造器
      31.        useStudentBuilder(Student::new);
      32.   }
      33.    private static void useStudentBuilder(StudentBuilder sb) {
      34.        Student s = sb.build("林青霞", 30);
      35.        System.out.println(s.getName() + "," + s.getAge());
      36.   }
      37. }

    • 使用说明

      Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数

  • 相关阅读:
    JavaScript基础(5)_运算符
    王道操作系统___第三章02
    PHP8中伪变量“$this->”和操作符“::”的使用-PHP8知识详解
    【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现
    视频录制后怎么裁剪?这里有可以学习的操作
    【Android】RxJava+Retrofit+OKHttp3实现数据上传
    如何低门槛开发有趣实用的ZigBee产品?
    深入浅出富文本编辑器
    如何扫码分享文件?二维码扫描预览文件的方法
    pytorch深度学习实战lesson7
  • 原文地址:https://blog.csdn.net/qq_69748833/article/details/133011301