Lambda表达式
使用前提
必须要有接口,并且接口中有且仅有一个抽象方法;必须有上下问推断,即方法的参数或者局部变量必须是Lambda对应的接口类型。
标准格式
- 一些参数
- 一个箭头
- 一段代码
(参数列表)->{ 方法体 }
省略格式
- 参数列表的数据类型可以省略
- 若参数列表中只有一个参数时,参数类型和()都可以省略
- 代码中只有一行语句的时候,{}、return、;都可以省略,但是要同时省略
Lambda的特点
延迟加载,使用Lambda表达式作为参数传递的时候,仅仅将参数传递,只有满足条件的时候才会调用接口中的方法,不会造成性能的浪费
Lambda可以被当作是匿名内部类的 “语法糖 ”
语法糖是指使用方便,但是原理不变的代码块
eg: for-each语法,底层还是迭代器
package lambda_test;
public class Test_01 {
public static void startThread(Runnable r){
new Thread(r).start();
}
public static void main(String[] args) {
//使用匿名内部类
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
//参数是函数式接口,可以使用lambda表达式
startThread(()->{
System.out.println(Thread.currentThread().getName());
});
//简化版的lambda表达式
startThread(()->
System.out.println(Thread.currentThread().getName()));
}
}
函数式接口
有且仅有一个抽象方法的接口
注解:
@FunctionalInterface检测接口是否是一个函数式接口
- 是:编译听过
- 否:编译失败
@FunctionalInterface
public interface MyInterface {
// public abstract可以省略
public abstract void method();
}
函数式接口的使用
- 可以作为方法的参数
- 可以作为方法的返回值类型
常用的函数式表达式
- Supplier接口
生产型接口,接口泛型指定什么类型,get()方法就会生产什么类型的对象数据
package Supplier_test;
import java.util.function.Supplier;
/**
* 使用Supplier<T>接口作为方法参数,通过Lambda表达式求出int数组中的最大值
*/
public class Test_02 {
//定义一个方法,使用Supplier接口作为方法的参数
public static int grtMax(Supplier<Integer> supplier){
return supplier.get();
}
//主方法
public static void main(String[] args) {
//定义数组
int[] arr={99,1000,23,4567,54,32};
//传入Lambda表达式
int maxValue = grtMax(()->{
int max=arr[0];
for (int i : arr) {
if(i>max){
max=i;
}
}
return max;
});
//输出
System.out.println("数组中的最大值为:"+maxValue);
}
}
- Consumer接口
用于消费数据,数据类型由决定
void accept(T t);//消费指定类型的数据
andThen();//将两个Consumer接口组合在一起对数据进行消费
package Consumer_test;
import java.util.function.Consumer;
/**
* Consumer<T>接口是消费式接口,旨在消费一个指定类型的数据,数据类型是T
* 抽象方法:void accept(T t);
*/
public class Test_01 {
/*
定义一个方法
方法的一个参数是String类型
一个参数是Consumer<T>接口
*/
public static void show(String name, Consumer<String> consumer){
//调用accept方法
consumer.accept(name);
}
public static void main(String[] args) {
String name="张三";
show(name,(name1)->{
//输出
System.out.println(name1);
//反转
String relName=new StringBuilder(name1).reverse().toString();
System.out.println(relName);
});
}
}
- Predicate接口
用于对某种数据类型的数据进行判断
boolean test(T t)
package Predicate_test;
import java.util.function.Predicate;
/**
* Predicate<T>函数式接口
* 作用:对某种类型的数据进行判断,返回一个Boolean值
* 方法 boolean test();
*/
public class Test_01 {
//定义方法,对String类型的字符串进行判断,借用Predicate<T>函数式接口
public static boolean checkString(String s, Predicate<String> pre){
return pre.test(s);
}
public static void main(String[] args) {
//定义字符串
String s="abcdefg";
//调用checkString方法
boolean b=checkString(s,(str)->{
return str.length()>5;
});
System.out.println(b);
}
}
- Function<T,R>接口
根据一个类型的数据得到另一个数据类型的数据
R apply(T t);//用于类型的转换
package Function_test;
import java.util.function.Function;
/*
* 测试andThen方法,用来进行组合操作
* 使用fun1.andThen(fun2).apply(T , t)
*
* 题目要求:
* 1.将String类型转为Integer类型
* 2.+10
* 3,将Integer类型转换为String
* 分析:
* 1.String->Integer Function<String,Integer>+10
* 2.Integer->String Function<Integer,String>
*/
public class Test_02 {
public static String change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){
return fun1.andThen(fun2).apply(s);
}
public static void main(String[] args) {
String string="123";
String str=change(string,(String s)->{
return Integer.parseInt(s)+10;
},(Integer i)->{
return i+" ";
});
System.out.println(str);
}
}