文章目录
- 函数式接口
-
- 常用的函数式接口 - JDK8之后
-
- Supplier:生产者
- Consumer:消费者
- Predicate:判断
- Function:转换
- Lambda表达式
-
- 作用
- 使用方法
- 方法引用
- 使用Lambda表达式简化函数式接口
-
- Supplier接口
- Consumer接口
- Predicate接口
- Function接口
函数式接口
@FunctionalInterface - 只有一个抽象方法的接口。
常用的函数式接口 - JDK8之后
Supplier:生产者
T get(); - 返回一个设定泛型的值。
Consumer:消费者
void accept(T t); - 获得一个泛型值并消费。
Consumer1.andThen(Consumer2)
先Consumer1消费,再Consumer2消费
Predicate:判断
boolean(T t); - 获得一个泛型值并进行判断,返回一个布尔值。
常用API:
and():pre1.and(pre2).test(t) 与
or():pre1.or(pre2).test(t) 或
negate():pre1.negate().test(t) 取反
Function:转换
用来做类型转换。
R apply(T t) - 将T类型转化为R类型。
常用API:
compose(Function fun)
如:fun1.compose(fun2).apply(t) - 先执行fun2,再执行fun1
andThen(Function fun)
如:fun1.andThen(fun2).apply(t) - 先执行fun1,再执行fun2
Lambda表达式
作用
匿名内部类的简化。
匿名内部类是实现函数式接口的时候,可以使用Lambda简化。
使用方法
原则:可推导,可省略。
1、要使用的接口和接口的方法是确定的,可以省略,保留方法参数和方法体。
2、方法参数类型可以省略。
3、前提:方法体中只有一句话,省略return关键字、分号、方法体的大括号,要省一起省。
注意!:Lambda表达式能取代匿名内部类,但是Lambda表达式不是类。
方法引用
当:
1、lambda表达式中只有一句代码 - 调用方法。
2、lambda表达式的参数就是代码中调用方法的参数。
方法引用 -> ::
使用方法引用的几种情况:
对象::实例方法名
类::静态方法名
类::new
类::实例方法名
this::本类方法名
super::父类方法名
Type::new 如:int[n]::new -创建新数组
上个this::本类方法名的例子
@FunctionalInterface
interface Richable{
void buy(String name);
}
public class this_demo {
//用来放将函数式接口作为参数的实例方法
public void buy(String name,Richable richable){
richable.buy(name);
}
//用来让this调用的实例方法
public void marry(String name){
System.out.println(name+"买房了");
}
//用来调用buy方法的实例方法
public void show(){
String name="lucy";
buy(name,this::marry);
}
public static void main(String[] args) {
//调用show方法输出,方便观察
new this_demo().show();
}
}
结果如下:
使用Lambda表达式简化函数式接口
Supplier接口
public class MySupplier {
/*Supplier 是一个函数式接口
可使用lambda简化,前提是使用Supplier作为方法参数
*/
public static Integer[] getSorted(Integer[] arr,Supplier<Integer[]> sup){
return sup.get();
}
public static void main(String[] args) {
Integer[] arr = {9,55,25,35,8};
System.out.println(Arrays.toString(getSorted(arr, () -> {
for (int i = 0; i < arr.length-1; i++) {
int max=i;
for (int j = i+1; j < arr.length; j++) {
if(arr[j]>arr[max]){
max=j;
}
}
if(i!=max) {
int temp = arr[max];
arr[max] = arr[i];
arr[i] = temp;
}
}
return arr;
})));
}
}
结果如下:
Consumer接口
public class MyConsumer {
public static void changName(String[] str, Consumer<String> con,Consumer<String> com){
for (String string: str) {
con.andThen(com).accept(string);
}
}
public static void main(String[] args) {
String str = "迪丽热巴,女;古力娜扎,女;马尔扎哈,男";
String[] ss = str.split(";");
changName(ss, s ->{
String[] strings = s.split(",");
System.out.println("姓名:"+strings[0]+",性别:"+strings[1]);
}, System.out::println);
}
}
结果如下:
Predicate接口
public class MyPredicate {
public static boolean judge(String str, Predicate<String> pre){
//判断名字长度
return pre.test(str);
}
public static boolean select(String str,Predicate<String> selectName,Predicate<String> selectGender){
//筛选
return selectName.and(selectGender).test(str);
}
public static void main(String[] args) {
String name = "泰达米尔";
System.out.println(judge(name,s -> s.length()<=3));
String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男","赵丽颖,女","胡歌,男"};
for (String str:array
) {
boolean keep = select(str,s -> {
return str.split(",")[0].length()==4;
},s -> {
return str.split(",")[1].equals("女");
});
if(keep){
System.out.println(str);
}
}
}
}
Function接口
public class MyFunction {
/*
1. 将字符串截取数字年龄部分,得到字符串;
2. 将上⼀步的字符串转换成为int类型的数字;
3. 将上⼀步的int数字累加100,得到结果int数字。
*/
public static int getNum(String str, Function<String,String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){
return fun3.compose(fun2).compose(fun1).apply(str);
//先执行fun1,再执行fun2,最后执行fun3
}
public static void main(String[] args) {
String str = "周杰伦,42";
int num = getNum(str,s-> str.split(",")[1],s -> Integer.valueOf(s),i -> i+100);
//分别做了字符串分割,类型准换和数值相加
System.out.println(num);
}
}
结果如下: