Java研学-Lambda表达式

一 Lambda表达式 – 箭头函数

1 含义

  JDK8首次将函数式编程引入到Java代码中;这是一种新型的方法参数传递的方式;直接将获取参数的步骤传递给需要该参数的方法中–Lambda表达式

2 特点

  1 简化代码

  2 多核友好

  3 面向对象思想不足

public class Play {public static void main(String[] args) {// 实现Runnable的优势在于他避免了单继承的局限性,但需要通过Thread构造器将实现接口的对象传给Thread// 多线程输出 匿名内部类实现run方法,通过Thread类调用start开启new Thread(new Runnable() {@Overridepublic void run() {System.out.println("多线程操作");}}).start();System.out.println("等价于");new Thread(()-> System.out.println("新多线程操作")).start();}
}

3 例子-自定义水果类,以普通方式与Lambda分别实现

自定义水果类

// 注解需导入lombok
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Fruit {private Long id;        // 编号private String name;    // 水果名private Integer price;  // 单价
}

普通方法

public class FruitTest {// 创建水果集合private static List<Fruit> fruits=new ArrayList<>();// 水果只需存储一次,进入直接初始化static {fruits.add(new Fruit(1L,"猕猴桃",6));fruits.add(new Fruit(2L,"苹果",5));fruits.add(new Fruit(3L,"苹果梨",4));fruits.add(new Fruit(4L,"橙子",7));fruits.add(new Fruit(5L,"草莓",6));fruits.add(new Fruit(6L,"山竹",11));}public static void main(String[] args) {// 查询所有6块钱的水果findByPrice();// 查询含苹果名字的水果findByName();}private static void findByPrice(){List<Fruit> prices=new ArrayList<>();for (Fruit f:fruits) {if(f.getPrice()==6){prices.add(f);}}System.out.println(prices);}private static void findByName(){List<Fruit> names=new ArrayList<>();for (Fruit f:fruits) {if(f.getName().contains("苹果")){names.add(f);}}System.out.println(names);}
}

Lambda

// 自定义接口
@FunctionalInterface
public interface IFruit {// 接口中定义统一操作规则 根据指定商品信息判断是否满足需求boolean test(Fruit f);
}// 使用
public class FruitTest {// 创建水果集合private static List<Fruit> fruits=new ArrayList<>();// 水果只需存储一次,进入直接初始化static {fruits.add(new Fruit(1L,"猕猴桃",6));fruits.add(new Fruit(2L,"苹果",5));fruits.add(new Fruit(3L,"苹果梨",4));fruits.add(new Fruit(4L,"橙子",7));fruits.add(new Fruit(5L,"草莓",6));fruits.add(new Fruit(6L,"山竹",11));}// 通过匿名内部类改造Lambda实现接口public static void main(String[] args) {// 查询所有6块钱的水果findFruitByI((p)->p.getPrice()==6);// 查询含苹果名字的水果findFruitByI(p->p.getName().contains("苹果"));}private static void findFruitByI(IFruit ifr){List<Fruit> ff =new ArrayList<>();for (Fruit f:fruits) {if(ifr.test(f)){ff.add(f);}}System.out.println(ff);}
}

4 Lambda表达式格式

  Lambda的固定格式核心符号是 ->
  左侧:表示通过Lambda表达式改造方法的参数部分
  右侧:表示通过Lambda表达式进行改造的方法的方法体

5 Lambda表达式改造前提

  必须是接口,并且接口中有且仅有一个抽象方法,为保证接口中只定义一个抽象方法,JDK8提出使用@FunctionaIInterface(函数式接口)

@FunctionalInterface
public interface IFruit {// 接口中定义统一操作规则 根据指定商品信息判断是否满足需求boolean test(Fruit f);
}

6 Lambda表达式特点演示

public class FruitTest {......public static void main(String[] args) {// ① 没有特殊要求改造方法的参数类型可以省List<String> list= Arrays.asList("大黄","大白","小黑");// foreach类似增强forlist.forEach(s-> System.out.println(s));// ② 改造方法仅有一个参数时()可以省,没有参数或有多个参数时()不能省new Thread(()-> System.out.println("多线程启动")).start();// 实例化时通过代码块为map赋值Map<String,String> map=new HashMap<String,String>(){{this.put("大黄","15kg");this.put("大白","12kg");}};// ③ 改造方法仅有一条代码{}与;都可以省去,若有多条代码则不能省去,一般改造方法只有一条代码map.forEach((k,v)->{System.out.println(k);System.out.println(v);});// ④ 改造方法仅一条代码,且为return语句时,return关键字可省去findFruitByI(new IFruit() {@Override public boolean test(Fruit f) {return f.getPrice()==6;}});findFruitByI(p->p.getPrice()==6);}private static void findFruitByI(IFruit ifr){List<Fruit> ff =new ArrayList<>();for (Fruit f:fruits) {if(ifr.test(f)){ff.add(f);}}System.out.println(ff);}
}

7 常见函数式接口

函数式接口参数类型返回类型说明
Consumer< T>消费型接口Tvoid对类型为T的对象进行操作,方法:void accept(T t)
Supplier< T>供给型接口T返回类型为T的对象 方法:T get();(可做工厂)
Function< T,R>函数型接口TR对类型为T的对象进行操作,并且返回结果是R类型(任意数据类型),方法:R apply(T t);
Predicate< T>断言型接口Tboolean判断类型为T的对象是否满足条件,返回值固定为布尔类型,方法 boolean test(T t)
public class FunctionPlay {// 创建水果集合private static List<Fruit> fruits = new ArrayList<>();// 水果只需存储一次,进入直接初始化static {fruits.add(new Fruit(1L, "猕猴桃", 6));fruits.add(new Fruit(2L, "苹果", 5));fruits.add(new Fruit(3L, "苹果梨", 4));fruits.add(new Fruit(4L, "橙子", 7));fruits.add(new Fruit(5L, "草莓", 6));fruits.add(new Fruit(6L, "山竹", 11));}public static void main(String[] args) {buy(36, new Consumer<Integer>() {@Overridepublic void accept(Integer integer) {System.out.println("买了"+integer+"元的水果");}});buy(456,(consumer)-> System.out.println("买了"+consumer+"元的水果"));int it=getRealLength("playthis", new Function<String, Integer>() {@Overridepublic Integer apply(String s) {return s.length();}});System.out.println(it);System.out.println(getRealLength("playthis",s -> s.length()));System.out.println(getCode(6, new Supplier<Integer>() {@Overridepublic Integer get() {return (int)(Math.random()*10);}}));System.out.println(getCode(8,()->(int)(Math.random()*10)));isOk(new Predicate<Fruit>() {@Overridepublic boolean test(Fruit fruit) {return fruit.getPrice()>8;}});}// 购买消费金额public static void buy(int moeny,Consumer<Integer> consumer){// 接口对象consumer调用方法accept传递参数moenyconsumer.accept(moeny);}// 获取长度(String真实长度)public static int getRealLength(String let, Function<String,Integer> fun){return fun.apply(let);}// 返回指定位数随机码public static String getCode(int num, Supplier<Integer> sup){// 创建StringBufferedStringBuffer sb=new StringBuffer();for (int i = 0; i < num; i++) {sb.append(sup.get());}return sb.toString();}// 判断水果是否超过8元public static void isOk(Predicate<Fruit> fp){for (Fruit f:fruits) {if(fp.test(f)){System.out.println(f.toString());}}}
}

8 方法引用

① 普通调用方法的方式

  对象.方法名([参数])

  类名.方法([参数])–必须被static修饰

② 方法引用

  进行Lambda表达式改造后,传递的操作已定义完毕(Java核心类库提供或者是其他程序员定义好的方法),可使用方法引用的方式调用

③ 方法引用的前提

  引用的方法必须是定义好的,必须是Lambda表达式改后的方法

④ 格式-- ::(引用运算符,两个引号)

::左侧 – 通过什么方式引用的即 对象名或类名

::右侧 – 调用方法的名字(方法引用只能引用无参方法,故不能写())

public class PlayMethod {public static void main(String[] args) {// 对象::方法名fun1();// 类名::静态方法fun2();// 类名::方法fun3();// 类名::newfun4();}// 方法引用有局限性,调用定义好的方法不能灵活应用// list.forEach(p-> System.out.println(p));private static void fun1(){List<String> list= Arrays.asList("大黄","大白","小黑");list.forEach(System.out::print);}// ()->Math.random()private static void fun2(){Supplier sup=Math::random;// get方法获取值System.out.println(sup.get());}// s->s.length()private static void fun3(){Function<String,Integer> fun=String::length;System.out.println(fun.apply("8537矿泉水"));}// 类名::new 构造器引用private static void fun4(){/*Supplier<String> sup=new Supplier<String>() {@Overridepublic String get() {return new String();}};*/// ()->new String();Supplier<String> sup=String::new;System.out.println(sup.get());}
}

9 延迟执行

又称延迟加载或懒加载

public class PlayMethod {public static void main(String[] args) {String name="大黄";String is="是";String color="黄色的";// 拼接 无论是否满足条件此刻都已经完成拼接存放在工具中了(性能浪费),满足条件才提供结果addString("ok",name+is+color);}private static void addString(String info, String s) {if("ok".equals(info)){System.out.println(s);}}
}

使用供给型接口实现延迟加载

public class PlayMethod {public static void main(String[] args) {String name="大黄";String is="是";String color="黄色的";// 拼接/*addString("no", new Supplier<String>() {@Overridepublic String get() {return name+is+color;}});*/addString("ok",()->name+is+color);}private static void addString(String info, Supplier<String> sup) {if("ok".equals(info)){// 判断通过才拼接字符串System.out.println(sup.get());}}
}

10 接口的多继承

① 接口能够定义的类成员

  成员常量:public static final 数据类型 常量名=值;

  抽象方法: 返回 方法名([参数]);

  JDK8后,在接口中可定义default和static方法,能够具有方法体

② 代码演示
定义接口A,包含抽象方法fun1()的default方法fun2(),以及static方法fun3();

public interface A {void fun1();default void fun2(){System.out.println("Afun2");}static void fun3(){System.out.println("Afun3");}
}

定义接口B,包含default方法fun2(),以及static方法fun3();


C类分别实现AB两个接口

public class C implements A,B{@Overridepublic void fun1() {}// 一个类实现多个接口时,若接口中default方法同名// 需重写default方法确认调用哪个default方法@Overridepublic void fun2() {B.super.fun2();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我不是DBA之慢SQL诊断方式

最近经常遇到技术开发跑来问我慢SQL优化相关工作&#xff0c;所以干脆出几篇SQL相关优化技术月报&#xff0c;我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到&#xff0c;尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…

C++ Core Guidelines解析 ( 好书推荐 )

C Core Guidelines是Bjarne和 Herb Sutter发起编写的一个开源项目&#xff0c;汇聚了 C社区多年来积累的宝贵经验&#xff0c;是非常全面的编程最佳实践指导&#xff0c;包括代码风格、函数、类、错误处理、性能优化等&#xff0c;可以说是C社区的集大成者。用Effective Modern…

网络安全缓冲区溢出实验

实验要求实验步骤函数 f00()函数 f01()函数 f02() 实验要求 C 程序 homework08.c 的主函数如下&#xff1a; int main(int argc, char * argv[]) { init_buf(Lbuffer, LEN);switch(argc) {case 1: f00(); break;case 2: f01(); break;case 3: f02(); break; default: f00(); …

JIT/Just-In-Time Compilation

即时编译&#xff08;Just-In-Time Compilation&#xff0c;JIT&#xff09;是一种将程序在运行时动态地编译成机器代码的编译技术。相对于传统的静态编译&#xff0c;即时编译将编译过程延迟到程序执行的时候进行&#xff0c;而不是在程序执行之前。这种方法允许编译器根据程序…

国内AI大模型已近80个,哪个最有前途?

目前&#xff0c;国内已经推出了近80个人工智能大模型&#xff0c;这些大模型各有优势&#xff0c;难以直接判断哪个最有前途。然而&#xff0c;以下几个大模型值得关注&#xff1a; 1、华为云盘古大模型&#xff1a;盘古大模型聚焦于为行业服务&#xff0c;包括自然语言、视觉…

【Markdown】Markdown 公式书写

Markdown 公式书写 文章目录 Markdown 公式书写公式风格上下标以及希腊字母分式根式等结构函数名运算符矩阵写法行列式写法多行公式数学字母样式 公式风格 Markdown公式方面主要是用的Latex数学公式的写法&#xff08;也是不完全相同&#xff0c;比Latax少了一些内容&#xff…

出错:I/O文件读取JAVA

I/O文件读取 /** author:xiaowang* date:2023/12/6* demand:读取java1班的数据* * */ package homework;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException;public class FileReadTest {public static void main(String[] args) …

月入9K, 95后夫妻转行网优:人生路远,我们只愿携手前行!

用心专注一门课&#xff0c;让教育改变更多人是优橙教育成立的初心与使命。 在优小橙的教育生涯里&#xff0c;见过许多学生&#xff0c;他们或是因为追求一份美好的前程来优橙&#xff1b;或是想要改变泥泞的现状来优橙&#xff1b;或是因为想要深耕通信行业来优橙……理由很多…

【头歌系统Python实验】字符串处理

目录 第1关&#xff1a;字符串的拼接&#xff1a;名字的组成 第2关&#xff1a;字符转换 第3关&#xff1a;字符串查找与替换 如果对你有帮助的话&#xff0c;不妨点赞收藏评论一下吧&#xff0c;爱你么么哒&#x1f618;❤️❤️❤️ 第1关&#xff1a;字符串的拼接&#x…

Linux--程序地址空间

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 [TOC](文章目录) 一、程序地址空间回顾 我们在讲C语言的时候&#xff0c;老师给大家画过这样的空间布局…

Qt-Q_OBJECT宏使用与“无法解析的外部符号qt_metacall/metaObject/qt_metacast“

有时候我们编写Qt类的时候&#xff0c;修改代码时直接加上Q_OBJECT宏&#xff0c;然后直接构建&#xff0c;会报如下错误&#xff1a; 这里的几个函数的声明是由Q_OBJECT宏引入的&#xff0c;而其对应的实现是由moc实现的&#xff0c;如果我们更新了代码但是没有执行qmake&…

基于Java学生宿舍管理系统

基于Java学生宿舍管理系统 功能介绍&#xff1a; 1、用户管理&#xff1a;系统需要提供用户注册、登录和权限管理功能。管理员可以创建和管理学生、宿舍员工等用户账号&#xff0c;并设置不同的权限级别。 2、宿舍管理&#xff1a;系统需要能够管理宿舍的基本信息&#xff0…

SQL小技巧:where条件后为什么要写1=1?

【微信公众号&#xff1a;跟强哥学SQL】 相信第一次看到下面这个SQL的同学心里都不免会产生疑问。 SELECT * FROM employeesWHERE 11 为什么要在where条件中使用11这样的写法&#xff1f;这不是废话吗&#xff1f; 其实还真不是。 为什么使用11这样的条件&#xff1f; 在…

Linux网卡命名规则

Linux网卡命名规则 网卡命名 一、为什么需要这个 服务器通常有多块网卡&#xff0c;有板载集成的&#xff0c;同时也有插在PCIe插槽的。Linux系统的命名原来是eth0,eth1这样的形式&#xff0c;但是这个编号往往不一定准确对应网卡接口的物理顺序。 为解决这类问题&…

基于FPGA的图像RGB转CIE-Lab实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1RGB颜色空间 4.2CIE-Lab颜色空间 4.3RGB转CIE-Lab算法原理 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的结果导入到matlab&#xff0c;并和matlab的仿真结果进行对比&#xff1a…

使用TouchSocket适配一个c++的自定义协议

这里写目录标题 说明一、新建项目二、创建适配器三、创建服务器和客户端3.1 服务器3.2 客户端3.3 客户端发送3.4 客户端接收3.5 服务器接收与发送 四、关于同步Send 说明 今天有小伙伴咨询我&#xff0c;他和同事&#xff08;c端&#xff09;协商了一个协议&#xff0c;如果使…

【Hadoop_01】Hadoop介绍与安装

1、Hadoop、HDFS、YARN介绍&#xff08;1&#xff09;Hadoop简介与优势&#xff08;2&#xff09;Hadoop组成&#xff08;3&#xff09;HDFS概述&#xff08;4&#xff09;YARN概述&#xff08;5&#xff09;MapReduce概述 2、安装&#xff08;1&#xff09;Centos7.5软硬件安装…

基于jsp+servlet+mybatis的简易在线选课系统

目录 一.数据库 1.数据库和表的创建 2.数据插入 二.代码实现 1.pojo类 &#xff08;1&#xff09;Course &#xff08;2&#xff09;User &#xff08;3&#xff09;Elective 2.mapper接口 &#xff08;1&#xff09;UserMapper &#xff08;2&#xff09;ElectiveMap…

前端开发实用技巧与经验分享

导语&#xff1a;在前端开发领域&#xff0c;掌握一些实用的技巧和经验可以帮助你更高效地完成任务。本文将分享一些前端开发的实用技巧和经验&#xff0c;帮助你在工作中更好地应对各种挑战。 一、使用开发者工具进行调试和优化 熟练掌握浏览器开发者工具的使用&#xff0c;…

vs 安装 qt qt扩展 改迅雷下载qt

Qt5.14.2安装教程和VS2019中的qt环境配置-CSDN博客 1 安装qt 社区版 免费 Download Qt OSS: Get Qt Online Installer 2 vs安装 qt vs tools 3 vs添加 qt添加 bin/cmake.exe 路径 3.1 扩展 -> qt versions 3.2 4 新版要源码安装 需要自己安装 安装独立安装的旧版 官网…