【Java基础概述-8】Lambda表达式概述、方法引用、Stream流的使用

1、Lambda表达式概述

        什么是Lambda表达式?

        Lambda表达式是JDK1.8之后的新技术,是一种代码的新语法

        是一种特殊写法。

        作用:“核心的目的是为了简化匿名内部类的写法”。

        

        Lambda表达式的格式:

        (匿名内部类被重写的形参列表){

        被重写的代码

        }

        使用前提:

        Lambda表达式并不能简化所有匿名内部类的写法

        Lambda表达式只能简化接口中只有一个抽象方法的匿名内部类形式。

        Lambda表达式只能简化函数式接口的匿名内部类写法:

        首先是接口,其次只有一个抽象方法。

1.1、函数式接口

        @FunctionalInterface函数式接口注解:

        一旦某个接口加上这个注解,这个接口有且只有一个抽象方法。

        这个接口可以用Lambda表达式简写。

        如Runnable线程任务接口:

public class LambdaDemo02 {
    public static void main(String[] args) {
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        });
        //Runnable
        //简写后:
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"执行");
        }).start();
    }
}

         1.如果Lambda表达式的方法体只有一行代码,可以省略大括号不写,同时省略分号。

        此时,如果这串代码有return语句,可以省略return 和;不写。

        2.参数类型可以不写

       3.如果只有一个参数,可以省略(和)不写

    public static void main(String[] args) {
        Set<Student> t = new TreeSet<>((o1,o2)->
           o1.getAge()-o2.getAge()
        );
        t.add(new Student("查尔斯",30));
        t.add(new Student("张三",20));
        t.add(new Student("里斯",23));
        System.out.println(t);
    }
}

public class LambdaDemo {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
//        names.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.print(s+" ");
//            }
//        });
        names.forEach(s-> System.out.println(s));
        System.out.println("\n-----");
        names.forEach(s -> System.out.println(s));


    }
}

2、方法引用

        概述:方法引用是为了进一步简化Lambda表达式的写法。

        方法引用的格式,类或者对象::引用的方案

        关键语法是“”::“”。

        


        方法引用的方式:

        1.静态方法的引用

        2.实例方法的引用

        3. 特定类型的引用

        4.构造器的引用

        例子:

public class MethodDemo01 {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
        names.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s+" ");
            }
        });
        System.out.println("\n-----");
        names.forEach(System.out::println);

    }
}

 2.1、静态方法的引用

        引用格式:

        类名::静态方法名。

        注意事项:

        1.被引用的方法参数列表要和函数式接口中的抽象方法的参数列表一致

        如果函数式接口中抽象方法有返回值,则被引用的方法也需要有返回值。

        如果函数式接口中的抽象方法没有返回值,则被引用的方法可以有返回值也可以没有

package _04方法引用方式一_静态方法的引用;

public class Student{
    private String name;
    private int age;


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    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 static int compareTo(Student o1,Student o2) {
        return o1.getAge()-o2.getAge();
    }
}

        

public class MethodDemo01 {
    public static void main(String[] args) {
        ArrayList<Student> s = new ArrayList<>();
        Student s1 = new Student("理查德", 30);
        Student s2 = new Student("查理斯", 25);
        Student s3 = new Student("张三", 20);
        Collections.addAll(s,s1,s2,s3);

//        Collections.sort(s,(o1,o2)->o1.getAge()-o2.getAge());
//        Collections.sort(s,(o3,o4)->Student.compareTo(o3,o4));
        Collections.sort(s,Student::compareTo);//类名::静态方法名
        s.forEach(System.out::println);
    }
}

2.2、实例方法的引用 

        格式:对象::实例方法。

        简化步骤:

        a.定义一个实例方法,把需要的代码放到实例方法中。

        b.被引用的方法参数必须和函数式接口中的抽象方法参数一样

        

public class MethodDemo {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
        names.forEach(s -> System.out.println());//对象::实例方法
        System.out.println("\n-----");
        names.forEach(System.out::println);//对象::实例方法
    }
}

2.3、特定类型的引用

        特定类型:类似String的包装类

        特定类型::方法

public class MethodDemo {
    public static void main(String[] args) {
        String[] strings =new String[]{"Jxx","sxxx","aaxx","Axxx","Bcc","bcc"};
//        Arrays.sort(strings, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareToIgnoreCase(o2);
//            }
//        });
//        Arrays.sort(strings, (String o1, String o2)-> o1.compareToIgnoreCase(o2));
        Arrays.sort(strings, String::compareToIgnoreCase);
        System.out.println("-------");
        for (String string : strings) {
            System.out.println(string);
        }
    }
}

2.4、构造器引入

                格式:类名::new

                引入的格式需要: s -> new Student(s) =>Student::new

                小结:方法引入可遇不可求

public class ConstractorDemo01 {
    public static void main(String[] args) {
        ArrayList<String> lists = new ArrayList<>();
        lists.add("java1");
        lists.add("java2");

        //集合默认只能转换成Object数组
//        Object[] array = lists.toArray();
//        System.out.println(Arrays.toString(array));
        //我们想转成字符串应该如何做?
        //最新的写法可以结合构造器引用实现!!
        String[] str1 =lists.toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
//      String[] str =   lists.toArray(s -> new String[s] );
      String[] str2 =   lists.toArray(String[]::new);
        System.out.println(Arrays.toString(str2));


    }
}

3、Stream流

        目标:了解Stream流的强大

        什么是Stream流?

        在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流的概念,用于解决已有集合/类库既有的弊端。

        Stream流能解决什么问题?

        可以解决已有集合类库或者数组API的弊端。

        Stream认为集合和数组的API很不友好,所以采用Stream流简化集合和数组的操作!!!
        

public class StreamDemo {
    public static void main(String[] args) {
        ArrayList<String> str = new ArrayList<>();
        str.add("张三");
        str.add("里斯");
        str.add("张无忌");
        str.add("张三丰");
        str.stream().filter(s -> s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
    }
}

3.1、Stream流的获取

        

 Stream流式思想思想的核心:

        先得到集合或者数组的Stream流(就是传送带)

        然后用这个Stream流操作集合或者数组元素。

         

        集合获取流的API接口:

        default stream<E> stream();

        集合获取stream流:

        list/set.stream()

        数组获取stream流:

        Arrays.stream(数组)/Stream.of(数组)

public class StreamDemo {
    public static void main(String[] args) {
        /*Collection集合获取Stream流*/
        Collection<String> collection =  new ArrayList<>();
        Stream<String> stream = collection.stream();
        /*Map集合获取Stream流*/
        HashMap<String, Integer> map = new HashMap<>();
        map.put("ID",1);
        map.put("money",100);
        Stream<String> stream1 = map.keySet().stream();//获取键流
        Stream<Integer> stream2 = map.values().stream();//获取值流
        Stream<Map.Entry<String, Integer>> stream3 = map.entrySet().stream();
        stream3.forEach(System.out::println);
        /*集合获取String流*/
        String[] s = new String[]{"张三","李四","王五"};
        Stream<String> stream4 = Arrays.stream(s);
        //或者
        Stream<String> stream5 = Stream.of(s);

    }
}

3.2、Stream流的常用API

        forEach():遍历

        count():统计个数

        filtert():过滤元素

        limit():取前几个元素

        skip():跳过前几个

        map(s->xxxx):加工方法

        concat():合并流        

        看懂下面代码即可弄懂

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==3;
            }
        }).filter(s->s.startsWith("张")).forEach(System.out::println);

        long count = list.stream().filter(s -> s.length() == 3).count();
        System.out.println(count);

        list.stream().filter(s->s.startsWith("张")).limit(1).forEach(System.out::println);
        list.stream().filter(s->s.startsWith("张")).skip(1).forEach(System.out::println);
    }
}

public class StreamDemo02 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");

        //把名字都加上"厉害的+xxxx"
        list.stream().map(s->"厉害的"+s).forEach(System.out::println);

//        把其创建成学生对象
        list.stream().map(s->new Student(s)).forEach(System.out::println);
    }
}
public class StreamDemo03 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        Stream<String> stream = list.stream();
        Stream<Integer> integerStream = Stream.of(10, 20, 40, 50);
        Stream<Object> concat = Stream.concat(stream, integerStream);
        concat.forEach(System.out::println);
    }
}

 3.3、Stream流的收集

        Stream流的作用是:把集合转换成一个传送带,借用Stream流的强大功能进行操作。

        但是实际开发中数据以最终形式还应该是集合,最终Stream流操作完毕以后还是要转换成集合。这就是Stream流。

        Stream流只是手段,集合才是目的

        格式:

        stream.collect(Collectors.toSet()/toList())

        stream.toArray(String[]::new)

public class StreamDemo {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("张三丰");
        one.add("张无忌");
        one.add("张小凡");
        one.add("周芷若");
        one.add("吕布");
        one.add("李小川");
        Stream<String> z = one.stream().filter(s -> s.startsWith("张"));
        /*
        * 收集成Set集合
        * */
//        Set<String> collect = z.collect(Collectors.toSet());
//        collect.forEach(System.out::println);
        /*
        * 收集成List集合
        * */
//        List<String> list = z.collect(Collectors.toList());
//        Iterator<String> iterator = list.iterator();
//        while (iterator.hasNext()) System.out.println(iterator.next());
        /*
        *
        * 转换成数组
        * */
//        String[] s =z.toArray(new IntFunction<String[]>() {
//            @Override
//            public String[] apply(int value) {
//                return new String[0];
//            }
//        })
//
        String[] s =z.toArray(String[]::new);
        for (String string : s) {
            System.out.println(string);
        }
    }

}

本次小结: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/453672.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[MYSQL数据库]--表内操作(CURD)

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、表的 Cre…

AI时代Python金融大数据分析实战:ChatGPT让金融大数据分析插上翅膀【文末送书-38】

文章目录 Python驱动的金融智能&#xff1a;数据分析、交易策略与风险管理Python在金融数据分析中的应用 实战案例&#xff1a;基于ChatGPT的金融事件预测AI时代Python金融大数据分析实战&#xff1a;ChatGPT让金融大数据分析插上翅膀【文末送书-38】 Python驱动的金融智能&…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:TimePicker)

时间选择组件&#xff0c;根据指定参数创建选择器&#xff0c;支持选择小时及分钟。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 TimePicker(options?: TimePickerOptions)…

【计算机网络】HTTPS协议

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;网络原理&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 HTTPS是什么&#xff1f; 为什么要加密&#xff1f; …

如何选择最佳文档管理系统?2024年11款企业DMS详细评测!

11款文档管理系统 (DMS)包括&#xff1a;1.PingCode 知识库&#xff1b;2.DocuWare &#xff1b;3.Dropbox Business &#xff1b;4.eFileCabinet &#xff1b;5.Google Drive &#xff1b;6.Laserfiche &#xff1b;7.LogicalDOC &#xff1b;8.M-Files &#xff1b;9.OnlyOff…

大龄全职宝妈的出路在哪里?怎么突破困境,实现财富自由?

我是电商珠珠 对于女性来说从怀孕到生子起码要经过最低2年的时间&#xff0c;这2年就是空窗期&#xff0c;有的女性需要三年甚至更多的时间去带孩子&#xff0c;别说让财富自由了&#xff0c;人身都很难自由。 特别是现在的大龄全职妈妈&#xff0c;明明还正值壮年&#xff0…

【网络协议】RPC、REST API深入理解及简单demo实现

目录 一、RPC二、REST三、代码3.1 RPC demo3.2 Rest API demo 一、RPC RPC 即远程过程调用&#xff08;Remote Procedure Call Protocol&#xff0c;简称RPC&#xff09;&#xff0c;像调用本地服务(方法)一样调用服务器的服务(方法)。通常的实现有 XML-RPC , JSON-RPC , 通信…

人工智能测试开发

随着人工智能在各行各业的广泛应用&#xff0c;学习并掌握AI技术在软件测试中的应用变得至关重要。不仅能使你跟上行业的发展趋势&#xff0c;还能提升你的竞争力。而且&#xff0c;市场对具备AI测试技能的测试工程师的需求正日益增长&#xff0c;这使得掌握这些技能能够帮助你…

MySQL知识点极速入门

准备SQL 创建数据库&#xff1a; 创建一个名为emptest的数据库 create database emptest; use emptest; 创建数据表&#xff1a; 设计一张员工信息表&#xff0c;要求如下&#xff1a; 1. 编号&#xff08;纯数字&#xff09; 2. 员工工号 (字符串类型&#xff0c;长度不超…

mac启动skywalking报错

这个命令显示已经成功 但是日志报错了以上内容。 然后去修改。vim .bash_profile 查看全局变量&#xff0c;这个jdk却是有2个。所以这个问题没解决。

考研C语言复习进阶(1)

目录 1. 数据类型介绍 1.1 类型的基本归类&#xff1a; 2. 整形在内存中的存储 2.1 原码、反码、补码 2.2 大小端介绍 3. 浮点型在内存中的存储 ​编辑 1. 数据类型介绍 前面我们已经学习了基本的内置类型&#xff1a; char //字符数据类型 short //短整型 int /…

VTK包围盒,AABB包围盒

1. 概述 包围盒是指能够包含三维图形的长方体&#xff0c;常常用于模型的碰撞检测。包围盒可以分成&#xff1a;轴对齐包围盒(AABB),有向包围盒(OBB)和凸包(Convex Hull) 今天就来实践一下AABB包围盒 2.绘制一个锥体 #include "vtkAutoInit.h" VTK_MODULE_INIT(v…

任务弹窗更新为任务对话框

1.设计初心 在玩家接取任务/交付任务时&#xff0c;界面弹出的UI &#xff0c;需要与玩家互动&#xff0c;点击“接取”“完成”。等等字样【改动前】频繁的手动点击会中断玩家跑图的流畅性&#xff0c;也降低了任务寻路系统的实际体验。于是现在变成类似FakeObj 对话框的模式…

Filebeat(Beats)详细介绍与使用

1. 什么是 Beats? Beats 是开源数据传送器&#xff0c;将其作为代理安装在服务器上&#xff0c;以将操作数据发送到 Elasticsearch。 Elastic提供Beats用于捕获&#xff1a; 审核数据&#xff1a;Auditbeat 日志文件和日志&#xff1a;Filebeat 云数据&#xff1a;Functio…

网络学习:9个计算机的“网络层”知识点

目录 一、IP 地址 1.1 分类表示法&#xff1a; 1.1.1 分类表示地址的其他说明 1.2 无分类编址 CIDR 二、IP 数据报文格式 Q: IP 报文里有什么&#xff1f;可以不按顺序或者字节来讲一讲 三、 路由概念 3.1 路由表 3.2 路由网络匹配 3.3 ARP 解析 3.4 RARP 逆地址解析…

matplotlib系统学习记录

日期&#xff1a;2024.03.12 内容&#xff1a;将matplotlib的常用方法做一个记录&#xff0c;方便后续查找。 基本使用 # demo01 from matplotlib import pyplot as plt # 设置图片大小,也就是画布大小 fig plt.figure(figsize(20,8),dpi80)#图片大小&#xff0c;清晰度# 准…

代码学习记录18

随想录日记part18 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.13 主要内容&#xff1a;今天的主要内容是二叉树的第七部分&#xff0c;主要涉及二叉搜索树的最近公共祖先 &#xff1b;二叉搜索树的最近公共祖先&#xff1b;删除二叉搜索树中的节点 。 23…

HQChart实战教程70-K线图增加成本线

HQChart实战教程70-K线图增加成本线 成本线Y轴子自定义刻度HQChart插件地址步骤1. 创建成本线2. 动态计算盈利值3. 删除成本线交流示例源码成本线 在K线图上,显示一个根当前账户持仓的成本线,可以快速看到盈利状态。方便盯盘。 效果入下图: 第1行是成本价 第2行是盈利点数…

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

基于大模型的 Agent 进行任务规划的10种方式

本文首发自博客 基于大模型的 Agent 进行任务规划的10种方式 基于大模型的 Agent 基本组成应该包含规划&#xff08;planning)&#xff0c;工具&#xff08;Tools)&#xff0c;执行(Action)&#xff0c;和记忆(Memory)四个方面&#xff0c;上一篇中重点讲了进行长记忆管理的 8…
最新文章