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

2023-09-19 08:27:32

2.6Stream流综合练习【应用】

  • 案例需求

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

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

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

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

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

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

  • 代码实现

    演员类

    public class Actor {
        private String name;
    ​
        public Actor(String name) {
            this.name = name;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    }

    测试类

    public class StreamTest {
        public static void main(String[] args) {
            //创建集合
            ArrayList<String> manList = new ArrayList<String>();
            manList.add("周润发");
            manList.add("成龙");
            manList.add("刘德华");
            manList.add("吴京");
            manList.add("周星驰");
            manList.add("李连杰");
      
            ArrayList<String> womanList = new ArrayList<String>();
            womanList.add("林心如");
            womanList.add("张曼玉");
            womanList.add("林青霞");
            womanList.add("柳岩");
            womanList.add("林志玲");
            womanList.add("王祖贤");
      
            //男演员只要名字为3个字的前三人
            Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);
      
            //女演员只要姓林的,并且不要第一个
            Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
      
            //把过滤后的男演员姓名和女演员姓名合并到一起
            Stream<String> stream = Stream.concat(manStream, womanStream);
      
            // 将流中的数据封装成Actor对象之后打印
            stream.forEach(name -> {
                Actor actor = new Actor(name);
                System.out.println(actor);
            }); 
        }
    }

3.方法引用

3.1体验方法引用【理解】

  • 方法引用的出现原因

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

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

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

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

  • 代码演示

    public interface Printable {
        void printString(String s);
    }
    ​
    public class PrintableDemo {
        public static void main(String[] args) {
            //在主方法中调用usePrintable方法
    //        usePrintable((String s) -> {
    //            System.out.println(s);
    //        });
            //Lambda简化写法
            usePrintable(s -> System.out.println(s));
    ​
            //方法引用
            usePrintable(System.out::println);
    ​
        }
    ​
        private static void usePrintable(Printable p) {
            p.printString("爱生活爱Java");
        }
    }

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方法

  • 代码演示

    public interface Converter {
        int convert(String s);
    }
    ​
    public class ConverterDemo {
        public static void main(String[] args) {
    ​
            //Lambda写法
            useConverter(s -> Integer.parseInt(s));
    ​
            //引用类方法
            useConverter(Integer::parseInt);
    ​
        }
    ​
        private static void useConverter(Converter c) {
            int number = c.convert("666");
            System.out.println(number);
        }
    }

  • 使用说明

    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方法

  • 代码演示

    public class PrintString {
        //把字符串参数变成大写的数据,然后在控制台输出
        public void printUpper(String s) {
            String result = s.toUpperCase();
            System.out.println(result);
        }
    }
    ​
    public interface Printer {
        void printUpperCase(String s);
    }
    ​
    public class PrinterDemo {
        public static void main(String[] args) {
    ​
            //Lambda简化写法
            usePrinter(s -> System.out.println(s.toUpperCase()));
    ​
            //引用对象的实例方法
            PrintString ps = new PrintString();
            usePrinter(ps::printUpper);
    ​
        }
    ​
        private static void usePrinter(Printer p) {
            p.printUpperCase("HelloWorld");
        }
    }
  • 使用说明

    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方法

  • 代码演示

    public interface MyString {
        String mySubString(String s,int x,int y);
    }
    ​
    public class MyStringDemo {
        public static void main(String[] args) {
            //Lambda简化写法
            useMyString((s,x,y) -> s.substring(x,y));
    ​
            //引用类的实例方法
            useMyString(String::substring);
    ​
        }
    ​
        private static void useMyString(MyString my) {
            String s = my.mySubString("HelloWorld", 2, 5);
            System.out.println(s);
        }
    }

  • 使用说明

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

3.6引用构造器【应用】

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

  • l格式

    类名::new

  • 范例

    Student::new

  • 练习描述

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

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

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

      Student build(String name,int age);

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

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

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

  • 代码演示

    public class Student {
        private String name;
        private int age;
    ​
        public Student() {
        }
    ​
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public int getAge() {
            return age;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    }
    ​
    public interface StudentBuilder {
        Student build(String name,int age);
    }
    ​
    public class StudentDemo {
        public static void main(String[] args) {
    ​
            //Lambda简化写法
            useStudentBuilder((name,age) -> new Student(name,age));
    ​
            //引用构造器
            useStudentBuilder(Student::new);
    ​
        }
    ​
        private static void useStudentBuilder(StudentBuilder sb) {
            Student s = sb.build("林青霞", 30);
            System.out.println(s.getName() + "," + s.getAge());
        }
    }

  • 使用说明

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

更多推荐

5.4 转换数据

5.4转换数据5.4.1哑变量处理类别型数据5.4.2离散化连续型数据1、等宽法2、等频法3、聚类分析法数据集E:/Input/ptest.csv5.4.1哑变量处理类别型数据数据分析模型中有相当一部分的算法模型都要求输入的特征为数值型,但实际数据中特征的类型不一定只有数值型,还会存在相当一部分的类别型,这部分的特征需

SpringSecurity 核心过滤器——CsrfFilter

文章目录前言什么是CSRF攻击解决方案检查Referer字段CsrfTokenSpringSecurity是如何防止CSRF攻击的开启关闭CSRF防御SpringSecurity的实现CSRF的原理CsrfTokenCsrfTokenRepositoryCsrfFilter分布式Session处理配置SpringSes

Python3接口自动化测试项目实战(WEB项目)

1.1接口测试项目搭建1.1.1教育局招生管理系统部署教育局招生管理系统是基于java+mysql,下面介绍它的部署过程。1.从我的网盘下载部署文件。2.安装jdk以及配置环境变量。点击文件进行安装。下一步下一步直接安装。本人的安装路径是C:\ProgramFiles\Java\jdk1.7.0_17。安装完成后需要设

诡异,明明更新成功了状态,查不出来了

作者:明明如月学长,CSDN博客专家,大厂高级Java工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。热门文章推荐:(1)《为什么很多人工作3年却只有1年经验?》(2)《从失望到精通:AI大模型的掌握与运用技巧》(3)《A

DBus笔记

包含2套总线:systembus,servicebus,权限不同,systembus需要kernel或root权限dbusdaemon进程提供服务,有systemd启动dbusdaemon,为systembus和servicebus分别启动一个daemon。nativeobject:收发消息的应用需要向dbus注册ob

【Java 基础篇】Java实现文件搜索详解

文件搜索是计算机应用中的一个常见任务,它允许用户查找特定文件或目录,以便更轻松地管理文件系统中的内容。在Java中,您可以使用各种方法来实现文件搜索。本文将详细介绍如何使用Java编写文件搜索功能,以及一些相关的内容。文件搜索的基本概念在开始之前,让我们了解一些与文件搜索相关的基本概念:搜索目标:搜索的目标可以是文件名

python | 手写一个python代码计时器,分别基于装饰器和上下文管理器两种方案实现

文章目录01传统方案02使用函数装饰器03使用上下文管理器01传统方案我们在编码的时候常常有函数计时的需求,通常都是直接使用python自带的time库来实现。importtimet0=time.time()...#要计时的代码elapsed=time.time()-t0print(f"耗时{elapsed}s")这种

Zygote Secondary:加速应用启动的未来之路

ZygoteSecondary:加速应用启动的未来之路1.引言在现代的移动应用开发中,启动速度和响应性能是用户体验的重要方面。然而,传统的Android进程管理方式在启动应用时会出现性能瓶颈,导致启动时间过长和资源占用过多。为了解决这一问题,Google引入了一个创新的技术——ZygoteSecondary。Zygot

网络电视机顶盒怎么样?百元价位最佳网络机顶盒排名

网络电视机顶盒无疑是家家户户必备的,用网络机顶盒可以看电视,玩游戏,上网课,K歌,购物等,你认为网络电视机顶盒怎么样?值不值得买?本期我盘点了百元价位段最佳网络机顶盒排名,想买网络机顶盒可以从以下五款中选择。榜一:泰捷WEBOX40S网络机顶盒推荐理由:极致性价比,超大内存泰捷WEBOX专注音视频技术处理、解码、传输有

云存储目前面临的3个问题

云存储目前面临的3个问题1、基础设施性能不一定要求越高越好,而是有多种性能区以供用户选择,但基本上还是要满足较低延迟,早期的云计算平台在由于忽略对后端存储投入而出现比较多的IO延迟。另外,被存储的数据中有70%是静态的,很少甚至不会再次被访问,那么将这些数据通过自动化的ILM(信息生命周期管理)沉降到更低成本的介质上去

靶场练习——SDcms文件上传漏洞靶场

文章目录前言一、寻找网站后台页面1、点击请登录,查看URL2、修改URL参数,找到后台登录页面二、登录后台管理系统1、不能使用爆破2、使用弱口令登录三、寻找文件上传点四、上传文件操作1、上传普通的图片文件,查看数据包2、尝试上传PHP文件3、上传phpinfo()函数,获取系统版本信息4、绕过过滤五、尝试上传websh

热文推荐