lamda表达式:
因为函数式接口中只有一个方法,所以使用Lamda表达式实现的必然是这个方法,就省略了public 等声明,直接进行方法体的重写;
使用Lamda表达式需要一个重要的实现要求: SAM(Single Abstract Method)
在之前的匿名内部类中存在一个问题:
IMessage msg = new IMessage(){ // 匿名内部类 public void send(String str){ System.out.println(str); } };
以上代码仅需要一个功能就是:
System.out.println(str);
但是却使用了完整的面向对象结构来表达;
那么为了简化这种结构,就引出了Lamda表达式:
public class Main { public static void main(String[] args) { IMessage msg = (str) ->{ System.out.println(str); }; msg.send("I am here!Lamda!"); } }
在下面的接口中只有一个send()方法,除此之外没有其它任何方法,所以这种接口就被称为函数式接口。
而只有函数式的接口才能被Lamda表达式接受。
@FunctionalInterface // 函数式接口 public interface IMessage { public void send(String str); public static IMessage getInstance(){ return new IMessage() { //静态的匿名内部类 @Override public void send(String str) { System.out.println(str); } }; } }
函数式接口中的abstract方法永远只能有一个,其后可以增加default、static的普通方法。
@FunctionalInterface // 函数式接口 public interface IMessage { public void send(String str); public default void sub(){ System.out.println("jianfa"); } public static void sum(){ System.out.println("jiafa "); } public static IMessage getInstance(){ return new IMessage() { //静态的匿名内部类 @Override public void send(String str) { System.out.println(str); } }; } }
Lamda表达式格式:
- 方法没有参数:() -> {};
- 方法有参数: (参数,参数) -> {};
- 如果现在只有一行语句返回:(参数,参数) -> 返回语句;
方法的引用:
相当于将某个类的方法使用另一个名称表示,并传入对应的参数,方法的功能都是一样。
存在四种格式:
- 引用静态方法:类名称 :: static方法
- 引用某个实例对象方法:实例化对象 :: 普通方法
- 引用特定类型的方法:特定类 :: 普通方法
- 引用构造方法:类名称 :: new
以泛型定义方法的格式应用函数式接口:
@FunctionalInterface public interface IFunction<P,R> { // R是返回值类型,P是参数 public R 转换 (P p) ; // R定义返回值类型,P定义参数 }
@FunctionalInterface public interface IFunctions<R> { // R是返回值类型 public R upper () ; }
package Demo_1_28_以泛型定义方法的格式应用函数式接口; public interface IFunctionss <P> {//P是参数类型 public int compare(P p1,P p2); }
package Demo_1_28_以泛型定义方法的格式应用函数式接口; public interface IFunctionsss <R>{ public R create(String s, int a); }
package Demo_1_28_以泛型定义方法的格式应用函数式接口; public class Main { public static void main(String[] args) { // :: 之前是返回值类型,:: 之后是某种方法,valueOf是static方法 IFunction<Integer,String> fun = String :: valueOf; // 两个参数,返回值是字符串,参数是Integer String str = fun.转换(100); //此时转换方法和valueOf是同一个方法 System.out.println(str.length()); // toUpperCase需要实例化对象才能使用,"www.baidu.com"就是一个字符串对象。 IFunctions<String> fun1 = "www.baidu.com" :: toUpperCase; // 返回支付串, System.out.println(fun1.upper()); //此时upper方法和toUpperCase是同一个方法 // 引用指定类的方法 IFunctionss<String> fun2 = String :: compareTo; System.out.println(fun2.compare("A","a")); //此时compare方法和compareTo是同一个方法 // 引用构造方法 IFunctionsss<Person> fun3 = Person :: new; System.out.println(fun3.create("张三",19)); //此时create方法和Person的构造方法是同一个方法 } }
方法引用并不是替代品,只是弥补了此项功能的不足,多出一种选择。
内建的函数式接口:
在系统之中专门提供有一个java.util.function的开发包,可以直接进行函数式接口的使用:
- 功能性函数式接口:接口都是以Function为后缀
接口定义 | 接口使用 |
@FunctionalInterface public interface Function<T,R> { public R apply (T t) ; }
|
import java.util.function.Function; public class Main { public static void main(String[] args) { Function<String,Boolean> fun = "** Hello" :: startsWith; System.out.println(fun.apply("**")); // true,此时的apply方法就是startsWith方法 } }
|
- 消费型函数式接口:只能够进行数据的处理操作,而没有任何的返回:
· 在进行系统数据输出的时候使用System.out.println();
接口定义 | 接口使用 |
|
import java.util.function.Consumer; public class Main { public static void main(String[] args) { Consumer<String> fun1 = System.out :: println; // System.out类下的println方法 fun1.accept("消费性接口应用,输出语句!"); // 此时的accept方法就是println方法 } }
|
- 供给型函数式接口:
· 在String类中提供了转先写的方法,这个方法没有接收参数,但是有返回值。
|- 方法: public String toLowerCase();
接口定义 | 接口使用 |
@FunctionalInterface public interface Supplier<T>{ public T get() ; }
|
import java.util.function.Supplier; public class Main { public static void main(String[] args) { Supplier<String> fun4 = "WWW.BAIDU.COM" :: toLowerCase; // 供给型,不接收任何参数,只有返回值 System.out.println(fun4.get()); // 此时get方法就是toLowerCase方法; } }
|
- 断言型函数式接口:进行判断处理
· 在String类中有一个方法是equalsIgnoreCase()方法;
接口定义 | 接口使用 |
@FunctionalInterface public interface Predicate<T>{ public boolean test (T t) }
|
import java.util.function.Predicate; public class Main { public static void main(String[] args) { // 断言型函数式接口 Predicate<String> fun5 = "www" :: equalsIgnoreCase; System.out.println(fun5.test("wwW")); } }
|
如果JDk提供的函数式接口已经满足我们的需求,那么就没有必要重写定义了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)