JDK8新特性【接口新特征、lambda语法、Supplier、Consumer、Function、Predicate】

目录

  • 一、关于接口的新特性
    • 1.1 jdk1.8之前的接口重要特性
    • 1.2 JDK8以后
        • 代码演示
    • 1.3 总结
        • 通过代码演示发现
        • 作用
  • 二、Lambda表达式[重点]
    • 2.1 将匿名内部类写法改写为lambda写法
    • 2.2 语法特点
        • 能够写成lambda形式的的前提
        • 语法特征
        • 代码演示
        • 深入理解lambda
    • 2.3 总结
  • 三、函数式接口
  • 3.1 概念
        • 什么是函数式接口
    • 四个典型的函数式接口
    • 3.2 Supplier
    • 3.3 Consumer
    • 3.4 Function
    • 3.5 Predicate
    • 3.6 总结
    • 思维导图
    • 最后

一、关于接口的新特性

1.1 jdk1.8之前的接口重要特性

  • 方法全都是抽象方法,即都没有方法体

1.2 JDK8以后

  • 允许接口中有被default和static修饰的方法带方法体
代码演示

接口USB

public interface USB {/** jdk8之前接口中只能有抽象方法* jdk8之后接口中被default的方法不是抽象方法,可以被重写,也可以不重写,不强制* 且方法还可以被static修饰,不能被重写,调用,只能通过接口调用*/int a =1;void fun1();// 默认抽象方法default void funNew(){// 被default修饰方法System.out.println("JDK8新特性:default修饰的方法要有方法体,实现类不强制重写");}static void funNew2(){// 被static修饰方法System.out.println("JDK8新特性:static修饰的方法要有方法体,实现类不可重写,不可调用,通过接口直接调用");}
}

实现类USBImpl

public class USBImpl implements USB{@Overridepublic void fun1() {System.out.println("重写旧方法");}@Overridepublic void funNew() {  //可以重写default修饰的方法}}

测试

public class USBImplTest {public static void main(String[] args) {USBImpl usb = new USBImpl();usb.fun1();usb.funNew();//usb.funNew2(); //实现类无法调用USB.funNew2();// 通过接口调用静态方法}
}

1.3 总结

通过代码演示发现
  • jdk8之后接口中被default的方法不是抽象方法,可以被重写,也可以不重写,不强制
  • 且方法还可以被static修饰,不能被重写,调用,只能通过接口调用
作用
  • 默认方法允许在不破坏现有实现的情况下向接口添加新功能。
  • 可以在不改变现有用户代码的情况下扩展接口。
  • 促进了API的演进,同时保持了向后的兼容性。

二、Lambda表达式[重点]

Lambda是匿名内部类的简化

Lambda 允许把函数(方法)作为一个方法的参数(函数作为参数传递到方法中)。


其实就是简化了匿名内部类的写法,更准确的说是对接口方法的重写的简化

2.1 将匿名内部类写法改写为lambda写法

使用lambda改写创建线程的方式

    public static void main(String[] args) {new Thread(new Runnable( ) {@Overridepublic void run() {for (int i = 0; i < 10001; i++) {System.out.println("正常实现Runnable完成线程" + i);}}}).start( );// 改成lambda形式// lambda是简化了匿名内部类,只剩下关于方法的参数列表和方法体// () -> {}new Thread(() -> {for (int i = 0; i < 10001; i++) {System.out.println("lambda完成线程"+i);}}).start( );// lambda是将方法当参数传递给另外一个方法}
}

2.2 语法特点

能够写成lambda形式的的前提
  1. 方法得有参数
  2. 参数的必须是接口
  3. 接口中的方法有且只能有一个!!!
语法特征

(参数) -> {执行语句}
或者
参数 -> 执行语句

  • 参数圆括号,当参数是一个的时候,圆括号可加可不加

    • (x) -> System.out.println(x)
    • x -> System.out.println(x)
  • 参数圆括号,当参数是多个的时候,圆括号必须加

    • (x,y) -> System.out.println(x+y)
  • 参数数据类型可写可不写,编译时会自动推断是什么类型

    • (x,y) -> System.out.println(x+y)
    • (int x,String y) -> System.out.println(x+y)
  • 执行语句的花括号,当且仅当执行语句只有一句时,可以不加花括号

    • new Thread(() -> System.out.println("匿名内部类开启线程")).start();
      
  • 执行语句的花括号,当执行语句不只一句时,必须加花括号

    • new Thread(() -> {int a = 1;a++;System.out.println("lambda开启线程" );}).start();
      
  • 关于返回值

    • 如果方法有返回值,且执行语句只有一行语句时,可以不用写return,直接写值

      test(() -> {return 1;});
      test(() -> 1);// 1就是return1
      
    • 如果代码比较多,又要返回数据,就必须写上return

      test(() -> {int a = 1;a++;return a;
      });
      
代码演示
ppublic class lambdaTest {/*1. **方法得有参数**2. **参数的必须是接口**3. **接口中的方法有且只能有一个!!!***/public static void main(String[] args) {// 如果lambda方法体中只有一行代码,{}可以省略show1(() -> System.out.println("无参无返回值"));// 如果lambda方法体中有多行代码,{}不能省略show1(() -> {System.out.println("无参无返回值1");System.out.println("无参无返回值2");System.out.println("无参无返回值3");});/** 有参数列表时,参数类型可以省略*/// 只有一个参数,()可以省略show2(b1 -> System.out.println(b1 * 10));// 参数数量>1,()不可以省略show3((c1,c2)->System.out.println(c1 + c2));// 有返回值,但是只有一行代码,{}可以省略,return也可以省略,-> 跟的就是返回值show4(d -> d);}//接口IA为参数,IA只有一个方法static void show1(IA ia){ia.a();}//接口IB为参数,IB只有一个方法static void show2(IB ib){ib.b(1);}//接口IC为参数,IC只有一个方法static void show3(IC ic){ic.c(1,2);}//接口ID为参数,ID只有一个方法static void show4(ID id){id.d(10);}
}
// 接口:IA只有一个无参无返回值方法
interface IA{void a();  //无参无返回值
}// 接口:IA只有两个个无参无返回值方法
interface IC{void c(int c1,int c2);  //参无返回值
}// 接口:IA只有一个无参无返回值方法
interface IB{void b(int b);  //无参无返回值
}// 接口:IA只有一个无参无返回值方法
interface ID{int d(int a);  //无参无返回值
}
深入理解lambda

为什么lambda要设计成,将方法(功能) 当参数传递给方法

  • 有了lambda,方法的功能不再局限,方法具体如何,要看看lambda功能如何
public class Demo3 {public static void main(String[] args) {double add = add(1, 2);System.out.println("add = " + add);double yunsuan = yunsuan((x, y) -> x / y, 1, 2);System.out.println("yunsuan = " + yunsuan);}/*** 已经的方法,参数列表是普通变量* 方法功能已经定好,唯一变化的是参数的值* 例如,这个add方法,是做两数相加,只能相加* 唯一能变的是,加的数不一样* --------------------------* 那如果,我想传入两个参数,让其相除返回结果?让其相乘返回结果?* 就需要重新设计方法*/public static double add(int a,int b){return a + b;}/*** 有了lambda之后,方法的执行功能就不再固定* 如何运行,要看调用时,传入的lambda是如何运行的*/public static double yunsuan(IE e,int a,int b){return e.jisuan(a, b);}}
interface IE {double jisuan(int a,int b);
}

2.3 总结

  • 其实 () -> {}
    • ()里面放的是重写方法的参数
    • {}里面放的是重写方法的方法体
    • 上面各种写法只是在特定情况下的简写,没有特定条件是没法简写的,就要按部就班来
  • lambda就是简化了匿名内部类的写法
  • lambda其实就是接口方法的重写
  • lambda的参数和返回值是根据接口方法决定的

三、函数式接口

3.1 概念

什么是函数式接口

接口中只有一个抽象方法时,该接口就是函数式接口.

Java提供了一个注解可以校验接口是否是函数式接口

@FunctionalInterface

Java中提供了几个特别常用的函数式接口

  • Supplier 供应,即返回一个数据 (无参有返回值的方法)
  • Consumer 消费,即给其传入数据做运算 (有参无返回值的方法)
  • Function 函数,传入2个参数,用于转换数据的 (有参有返回值的方法)
  • Predicate 判断,返回时boolean (有参,返回值是boolean)

四个典型的函数式接口

3.2 Supplier

  • Supplier.java源码
@FunctionalInterface
public interface Supplier<T> {/*** Gets a result.** @return a result*/T get();
}
// 该接口用来返回一个数据,所以叫供应商
// 其实就是无参数有返回值的接口,用的时候就是无参有返回值的lambda

练习,设计方法,通过Supplier接口,获得字符串的长度

		/** Supplier接口 ---顾名思义:供应,提高*  提供的方法--- T get();*  不需传入参数,就有返回值*///利用Supplier接口,实现获得字符串长度功能int i = get(() -> "java".length());System.out.println("i = " + i);// i = 4//参数为Supplier接口的方法public static int get(Supplier<Integer> supplier){return supplier.get();}

3.3 Consumer

JDK中Consumer.java源码

@FunctionalInterface
public interface Consumer<T> {/*** Performs this operation on the given argument.* 给传入一个值,对该值进行操作* @param t the input argument*/void accept(T t);
}
// 其实就是有参数无返回值的接口,用的时候就是有参无返回值的lambda

练习:设计方法,传入字符串,将字符串全部转大写,后输出

 		/** Consumer接口 ---顾名思义:消费,消耗*  提供的方法--- void accept(T t);*  需传入参数,无返回值*///利用Consumer接口,实现字符串转大写功能String s = "java";accept(c -> System.out.println(c.toUpperCase()),s);// JAVA//参数为Consumer接口的方法public static void accept(Consumer<String> consumer,String s){consumer.accept(s);}

3.4 Function

JDK中Function.java源码

@FunctionalInterface
public interface Function<T, R> {/*** Applies this function to the given argument.** @param t the function argument* @return the function result*/R apply(T t);
}
// 该接口用于,转换数据
// 其实就是有参数有返回值的接口,用的时候就是有参有返回值的lambda

利用Function,实现字符串数字转为整形数字功能

	 	/** Function<T, R>接口 ---顾名思义:函数,功能*  提供的方法--- R apply(T t);*  将T转换乘R类型 ,即转换数据*///利用Function,实现字符串数字转为整形数字功能String s2 = "111";Integer apply = apply(f -> Integer.parseInt(f), s2);System.out.println("apply = " + apply);// apply = 111//参数为Function接口的方法public static Integer apply(Function<String,Integer> function,String s){return function.apply(s);}

3.5 Predicate

JDK中Predicate.java源码

@FunctionalInterface
public interface Predicate<T> {/*** Evaluates this predicate on the given argument.** @param t the input argument* @return {@code true} if the input argument matches the predicate,* otherwise {@code false}*/boolean test(T t);
}

判断数据是否是偶数

   /** Predicate接口 ---顾名思义:判断,断定*  提供的方法--- boolean test(T t);*  提供判断方法*///利用Predicate接口,实现判断是否时偶数功能int i1 = 2;boolean b = predicate(a -> a % 2 == 0, i1);System.out.println("b = " + b); // b = true//参数为Predicate接口的方法public static boolean predicate(Predicate<Integer> predicate,Integer integer){return predicate.test(integer);}

3.6 总结

  • Supplier接口的方法一般用于 获得数据
  • Consumer接口的方法 一般用于 处理数据
  • Function接口的方法一般用于 转换数据
  • Predicate接口的方法一般用于 判断数据

思维导图

在这里插入图片描述


最后

如果感觉有收获的话,点个赞 👍🏻 吧。
❤️❤️❤️本人菜鸟修行期,如有错误,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍在这里插入图片描述

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

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

相关文章

ISO17025认证是什么?怎么做?

ISO17025认证是一种国际通用的实验室质量管理体系认证&#xff0c;其目标是确保实验室的技术能力、管理水平以及测试结果的可靠性和准确性达到国际认可的标准。该认证由国际标准化组织&#xff08;ISO&#xff09;和国际电工委员会&#xff08;IEC&#xff09;联合发布&#xf…

pytorch神经网络训练(AlexNet)

导包 import osimport torchimport torch.nn as nnimport torch.optim as optimfrom torch.utils.data import Dataset, DataLoaderfrom PIL import Imagefrom torchvision import models, transforms 定义自定义图像数据集 class CustomImageDataset(Dataset): 定义一个自…

美丽的拉萨,神奇的布达拉宫

原文链接&#xff1a;美丽的拉萨&#xff0c;神奇的布达拉宫 2022年11月30日&#xff0c;可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT-3.5&#xff0c;将人工智能的发展推向了一个新的高度。2023年11月7日&#xff0c;OpenAI首届…

TcpClient 服务器、客户端连接

TcpClient 服务器 TcpListener 搭建tcp服务器的类&#xff0c;基于socket套接字通信的 1 创建服务器对象 TcpListener server new TcpListener(IPAddress.Parse("127.0.0.1"), 3000); 2 开启服务器 设置最大连接数 server.Start(1000); 3 接收客户端的链接,只能…

Android帧绘制流程深度解析 (二)

书接上回&#xff1a;Android帧绘制流程深度解析 &#xff08;一&#xff09; 5、 dispatchVsync&#xff1a; 在请求Vsync以后&#xff0c;choreographer会等待Vsync的到来&#xff0c;在Vsync信号到来后&#xff0c;会触发dispatchVsync函数&#xff0c;从而调用onVsync方法…

手机和模拟器的 Frida 环境配置

目录 一、配置 JDK 和 android 环境 二、连接设备和查看权限 1、连接设备 2、查看手机权限 三、手机配置 Frida 1、frida-server下载 2、验证 四、模拟器配置 Frida 1、下载模拟器并调节成手机版&#xff1a; 2、连接并查看架构 3、配置并开启 x86 的 frida-serve…

Phybers:脑纤维束分析软件包

摘要 本研究提供了一个用于分析脑纤维束数据的Python库(Phybers)。纤维束数据集包含由表示主要白质通路的3D点组成的流线(也称为纤维束)。目前已经提出了一些算法来分析这些数据&#xff0c;包括聚类、分割和可视化方法。由于流线的几何复杂性、文件格式和数据集的大小(可能包…

HTML静态网页成品作业(HTML+CSS)—— 环保主题介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

多层tablayout+ViewPager,NestedScrollView+ViewPager+RecyclerView,嵌套吸顶滑动冲突

先看实现的UI效果 其实就是仿BOSS的页面效果&#xff0c;第二层tab下的viewpager滑到最右边再右滑&#xff0c;就操作第一层viewpager滑动。页面上滑时把第一层tab和vp里的banner都推出界面&#xff0c;让第二层tab吸顶。 滑上去第二个tab块卡在顶部&#xff0c;如图 我混乱…

React 渲染函数render、初始化函数、更新函数运行了两次,原因为何,如何解决? React.StrictMode

文章目录 Intro官网解释解决另一篇官网文章——初始化函数或更新函数运行了两次 Intro 我在用 react 写一个 demo &#xff0c;当我在某个自定义组件的 return 语句之前加上一句log之后&#xff0c;发现&#xff1a;每次页面重新渲染&#xff0c;该行日志都打印了两次&#xf…

vue-loader

Vue Loader 是一个 webpack 的 loader&#xff0c;它允许你以一种名为单文件组件 (SFCs)的格式撰写 Vue 组件 起步 安装 npm install vue --save npm install webpack webpack-cli style-loader css-loader html-webpack-plugin vue-loader vue-template-compiler webpack…

论文阅读Rolling-Unet,卷积结合MLP的图像分割模型

这篇论文提出了一种新的医学图像分割网络Rolling-Unet&#xff0c;目的是在不用Transformer的前提下&#xff0c;能同时有效提取局部特征和长距离依赖性,从而在性能和计算成本之间找到良好的平衡点。 论文地址&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/2…

618购物狂欢节有哪些数码好物值得抢购?年终必备神器清单大揭秘!

一年一度的“618年中大促”即将拉开帷幕&#xff0c;大家是否已经挑选好了心仪的宝贝呢&#xff1f;那些平时心仪已久的商品&#xff0c;是否总期待着在价格最优惠时收入囊中&#xff1f;毫无疑问&#xff0c;618就是这样一个绝佳的时机&#xff0c;因为各大电商平台都会纷纷推…

Lecture2——最优化问题建模

一&#xff0c;建模 1&#xff0c;重要性 实际上&#xff0c;我们并没有得到一个数学公式——通常问题是由某个领域的专家口头描述的。能够将问题转换成数学公式非常重要。建模并不是一件容易的事&#xff1a;有时&#xff0c;我们不仅想找到一个公式&#xff0c;还想找到一个…

群晖NAS安装配置Joplin Server用来存储同步Joplin笔记内容

一、Joplin Server简介 1.1、Joplin Server介绍 Joplin支持多种方式进行同步用户的笔记数据&#xff08;如&#xff1a;Joplin自己提供的收费的云服务Joplin Cloud&#xff0c;还有第三方的云盘如Dropbox、OneDrive&#xff0c;还有自建的云盘Nextcloud、或者通过WebDAV协议来…

长沙干洗服务,打造您的专属衣橱

长沙干洗服务&#xff0c;用心呵护您的每一件衣物&#xff01;致力于为您打造专属的衣橱&#xff0c;让您的每一件衣物都焕发出独特的魅力。 我们深知每一件衣物都承载着您的故事和情感&#xff0c;因此我们会以更加细心的态度对待每一件衣物。无论是您心爱的牛仔裤&#xff0c…

sizeof和strlen

1.sizeof和strlen的对比 1.1sizeof sizeof是计算变量所占内存空间大小的&#xff0c;单位是&#xff1a;字节 如果操作数是类型的话&#xff0c;计算的是使用类型创建的变量所占内存空间的大小。 sizeof只关注占用内存空间的大小&#xff0c;不在乎内存中存放的是什么数据 …

QML Canvas 代码演示

一、文字阴影 / 发光 Canvas{id: root; width: 400; height: 400onPaint: //所有的绘制都在onPaint中{var ctx getContext("2d") //获取上下文// 绘制带阴影的文本ctx.fillStyle "#333" //设置填充颜色ctx.fillRect(0, 0, root.width, root.height…

Stability AI发布新版文生图模型:依然开源

Stability AI最近发布了Stable Diffusion 3 Medium&#xff08;简称SD3 Medium&#xff09;&#xff0c;这是其最新的文生图模型&#xff0c;被官方称为“迄今为止最先进的开源模型”。SD3 Medium的性能甚至超过了Midjourney 6&#xff0c;特别是在生成手部和脸部图像方面表现出…

一杯咖啡的艺术 | 如何利用数字孪生技术做出完美的意式浓缩咖啡?

若您对数据分析以及人工智能感兴趣&#xff0c;欢迎与我们一起站在全球视野关注人工智能的发展&#xff0c;与Forrester 、德勤、麦肯锡等全球知名企业共探AI如何加速制造进程&#xff0c; 共同参与6月20日由Altair主办的面向工程师的全球线上人工智能会议“AI for Engineers”…