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为后缀
接口定义 | 接口使用 |
|
|
- 消费型函数式接口:只能够进行数据的处理操作,而没有任何的返回:
· 在进行系统数据输出的时候使用System.out.println();
接口定义 | 接口使用 |
|
|
- 供给型函数式接口:
· 在String类中提供了转先写的方法,这个方法没有接收参数,但是有返回值。
|- 方法: public String toLowerCase();
接口定义 | 接口使用 |
|
|
- 断言型函数式接口:进行判断处理
· 在String类中有一个方法是equalsIgnoreCase()方法;
接口定义 | 接口使用 |
|
|
如果JDk提供的函数式接口已经满足我们的需求,那么就没有必要重写定义了。