函数式接口
1. 函数式接口概述
函数式接口:有且仅有一个抽象方法的接口(Lambda表达式的前提)
建议加上注解体现函数式接口:@FunctionalInterface
2. 函数式接口作为方法的参数
就和Lambda 无参传递一样
package Lambda;
//测试类
public class Demo {
public static void main(String[] args) {
//函数式接口
//匿名内部类的方式
StartThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程启动了");
//Thread-1线程启动了
}
});
//Lambda表达式方式
StartThread(() -> {
System.out.println(Thread.currentThread().getName() + "线程启动了");
//Thread-0线程启动了
});
}
public static void StartThread(Runnable r) {
new Thread(r).start();
}
}
3. 函数式接口作为方法的返回值
案例是比较器(不太熟悉要注意)
package Lambda;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
//测试类
public class Demo {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("cc");
arrayList.add("a");
arrayList.add("ddd");
arrayList.add("bbbb");
System.out.println("排序前:" + arrayList);//排序前:[cc, a, ddd, bbbb]
//自然排序(不熟练)
Collections.sort(arrayList);
System.out.println("排序后:" + arrayList);//排序后:[a, bbbb, cc, ddd]
//选择器排序
Collections.sort(arrayList, stringComparator());
System.out.println("排序后:" + arrayList);//排序后:[a, cc, ddd, bbbb]
}
public static Comparator<String> stringComparator() {
/*
Comparator<String> comp = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
};
return comp;*/
//简写
/*return new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
};*/
//Lambda表达式
//return (String s1, String s2)->{return s1.length()-s2.length();};
//简化
return (s1, s2) -> s1.length() - s2.length();
}
}
4. 常用的函数式接口
- Supplier接口
- Consumer接口
- Predicate接口
- Function接口
Supplier接口:
Supplier< T >:包含一个无参的方法
- T get():获得结果
- 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
- Supplier接口也被称为生产型接口加粗样式,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用
package Lambda;
import java.util.function.Supplier;
//测试类
public class Demo {
public static void main(String[] args) {
String s = getString(() -> "wts");//得到数据的格式用Lambda
System.out.println(s);//wts
Integer i = getInteger(() -> 100);
System.out.println(i);//100
}
public static String getString(Supplier<String> sup) {
return sup.get(); //总是把get给忘记
}
public static Integer getInteger(Supplier<Integer> sup) {
return sup.get();
}
}
案例:数组最大值
package Lambda;
import java.util.function.Supplier;
//测试类
public class Demo {/*数组最大值*/
public static void main(String[] args) {
int[] arr = {90, 20, 10, 50, 100};
Integer maxvalue = getInteger(() -> {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
});
System.out.println(maxvalue);//100
}
public static Integer getInteger(Supplier<Integer> sup) {
return sup.get();
}
}
Consumer接口:
Consumer< T >:包含两个方法
- void accept(T):对给定的参数执行此操作
- default Consumer andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作
- Consumer接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
package Lambda;
import java.util.function.Consumer;
//测试类
public class Demo {
public static void main(String[] args) {
// operatorString("文天圣", new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);//文天圣
// }
// });
//operatorString("文天圣", s -> System.out.println(s));//文天圣
//operatorString("文天圣", System.out::println);//文天圣
operatorString("文天圣", System.out::println, s -> {
System.out.println(new StringBuilder(s).reverse().toString());
});
//文天圣
//圣天文
}
//操作字符串
public static void operatorString(String name, Consumer<String> con) {
con.accept(name);//accept() 对字符串进行操作
}
public static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {
con1.andThen(con2).accept(name); //先操作con1 然后操作con2
}
}
Consumer练习
按要求打出
package Lambda;
import java.util.function.Consumer;
//测试类
public class Demo {
public static void main(String[] args) {
String[] strArray = {"wts,20", "wyx,30", "xwb,60"};
printInfo(strArray, (String str) -> {
String name = str.split(",")[0];//split用法不熟练: 将字符串按照要求分割成字符串数组
System.out.print("姓名:" + name);
}, (String str) -> {
String age = str.split(",")[1];
System.out.println(",年龄:" + age);
});
}
//Consumer
public static void printInfo(String[] strarray, Consumer<String> con1, Consumer<String> con2) {
for (String str : strarray) {
con1.andThen(con2).accept(str);
}
}
}
//姓名:wts,年龄:20
//姓名:wyx,年龄:30
//姓名:xwb,年龄:60
Predicate接口:
- boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
- default Predicate negate():返回一个逻辑的否定,对应逻辑非
- default Predicate and(Predicate other):返回一个组合判断,对应短路与
- default Predicate or(Predicate other):返回一个组合判断,对应短路或
- Predicate接口通常用于判断参数是否满足指定的条件
test和negate.test
package Lambda;
import java.util.function.Predicate;
//测试类
public class Demo {
public static void main(String[] args) {
boolean b1 = checkString("hello", (String s) -> {
return s.length() > 8;
});
System.out.println(b1);//false
//简化
boolean b2 = checkString("hello", s -> s.length() > 8);
System.out.println(b2);//false
boolean a1 = checkString("helloworld", s -> s.length() > 8);
System.out.println(a1);//true
}
public static boolean checkString(String s, Predicate<String> pre) {
return pre.test(s);//对指定的参数s判断,判断条件由Lambda决定
//return pre.negate().test(s); //判断和上面相反
}
}
and 和 or
package Lambda;
import java.util.function.Predicate;
//测试类
public class Demo {
public static void main(String[] args) {
boolean b2 = checkString("hello", s -> s.length() > 8, s -> s.length() < 15);
System.out.println(b2);//false 逻辑与 true+false->false
boolean a1 = checkString("helloworld", s -> s.length() > 8, s -> s.length() < 15);
System.out.println(a1);//true 逻辑与 true+true->true
}
//同一个字符串给出两个判断,然后把判断结果用 ‘逻辑与的结果’ 作为最终的结果
public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.and(pre2).test(s);
}
}
package Lambda;
import java.util.function.Predicate;
//测试类
public class Demo {
public static void main(String[] args) {
boolean b2 = checkString("hello", s -> s.length() > 8, s -> s.length() < 15);
System.out.println(b2);//true 逻辑或 true+false->true
boolean a1 = checkString("helloworld", s -> s.length() > 8, s -> s.length() < 15);
System.out.println(a1);//true 逻辑或 true+true->true
}
public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.or(pre2).test(s);
}
}
案例:把名字三个字,年龄大于24的学生,加入集合并且遍历出来
我自个写的:
package Lambda;
import java.util.ArrayList;
import java.util.function.Predicate;
//测试类
public class Demo {
public static void main(String[] args) {
String[] str = {"wts,20", "xwb,26", "lx,23", "ab,30", "cde,29"};
ArrayList<String> arrayList = new ArrayList<>();
for (String s : str) {
Boolean a = checkStudent(s,
s1 -> s1.split(",")[0].length() > 2 //名字长度大于2
, s1 -> Integer.valueOf(s1.split(",")[1]) > 24);//年龄大于24
if (a) {//两个条件同时满足
arrayList.add(s);
}
}
//遍历结果
for (String s : arrayList) {
System.out.println(s);
}
}
//同时满足
public static Boolean checkStudent(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.and(pre2).test(s);
}
}
老师写的:u1s1确实有点东西的
package Lambda;
import java.util.ArrayList;
import java.util.function.Predicate;
//测试类
public class Demo {
public static void main(String[] args) {
String[] str = {"wts,20", "xwb,26", "lx,23", "ab,30", "cde,29"};
ArrayList<String> arrayList = checkStudent(str,
s -> s.split(",")[0].length() > 2, //名字长度大于2
s -> Integer.parseInt(s.split(",")[1]) > 24 //年龄大于24
);
//遍历
for (String s : arrayList) {
System.out.println(s);
}
//xwb,26
//cde,29
}
public static ArrayList<String> checkStudent(String[] strarray, Predicate<String> pre1, Predicate<String> pre2) {
ArrayList<String> arrayList = new ArrayList<>();
for (String s : strarray) {//遍历数组
if (pre1.and(pre2).test(s)) {//如果满足指定条件
arrayList.add(s);
}
}
return arrayList;
}
}
Function接口
- R apply(T t):将此函数应用于给定的参数
- default Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
- Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值
package Lambda;
import java.util.function.Function;
//测试类
public class Demo {
public static void main(String[] args) {
//int转换成string类型 输出
convert(100, s -> String.valueOf(s));//100
convert(100, String::valueOf);//100
//string类型转换成int类型 输出
convert("500", s -> Integer.parseInt(s));//500
convert("500", Integer::parseInt);//500
//把String 转换 成 int类型;加上整数转换成string ; 输出
convert("500", Integer::parseInt, i -> String.valueOf(i + 100));
}
//int转换成string类型 输出
public static void convert(Integer i, Function<Integer, String> fun) {
String s = fun.apply(i);
System.out.println(s);
}
//string类型转换成int类型 输出
public static void convert(String s, Function<String, Integer> fun) {
Integer str = fun.apply(s);
System.out.println(str);
}
//把String 转换 成 int类型;加上整数转换成string ; 输出
public static void convert(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
String str = fun1.andThen(fun2).apply(s);
System.out.println(str);
}
}
不熟练:
- String转换成Integer,
Integer.parseInt(s)
- Integer转换成String,
String.valueOf(s)
案例:七十年后年龄:
package Lambda;
import java.util.function.Function;
//测试类
public class Demo {
public static void main(String[] args) {
String s = "wts,20";
String age = s.split(",")[1];
after(age, Integer::parseInt, integer -> String.valueOf(integer += 70));//90
}
//得到年龄部分,转换成int
//年龄+70, 输出
public static void after(String arr, Function<String, Integer> fun1, Function<Integer, String> fun2) {
String ss = fun1.andThen(fun2).apply(arr);
System.out.println(ss);
}
}