1、Function<T, R>: 函数型接口
2、抽象方法:R apply(T t) 方法提供把一个数据类型转换为另一个数据类型的规则
3、作用:
如果需要定义一个函数,接收一个数据,将数据进行处理,完成之后,还能返回一个结果,就可以使用函数型接口,以前我们只能传递处理好之后的数据,或者将原始数据传入方法,现在可以传入处理方式
4、提供其他功能:
Function andThen(Function f):在调用者处理方式之后,再进行参数的处理方式调用
案例1 : 定义一个方法功能, 根据整数x,计算出对应整数y, x数据由客户给出, y数据的计算方式根据客户要求决定
1) 客户1 : y为x的2倍
2) 客户2 : y与x相等
3) 客户3 : y为x的平方
4) ...
案例2 : 定义一个方法功能, 根据字符串x,计算出对应整数y, x数据由客户给出, y数据的计算方式根据客户要求决定
1) 客户4 : x为”6” , 计算出x转换成整数后, 2倍结果
2) 客户5 : x为”-2”, 计算出x转换成整数后, +1的结果
...
import java.util.function.Function; public class FunctionInterfaceUse { public static void main(String[] args) { // 1)客户1 : y为x的2倍 Function<Integer,Integer> fun = x -> 2*x; System.out.println(testFunction(5,fun));// 10 // 2)客户2 : y与x相等 Function<Integer,Integer> fun2 = x ->x; System.out.println(testFunction(666,fun2));// 666 // 3)客户3 : y为x的平方 Function<Integer,Integer> fun3 = x -> x*x; System.out.println(testFunction(10,fun3));// 100 //4)客户4 : x为”6” , 计算出x转换成整数后, 2倍结果 Function<String,Integer> fun4 = x -> Integer.parseInt(x); System.out.println(testFunction2("6",fun4,fun));// 12 //5)客户5 : x为”-2”, 计算出x转换成整数后, +1的结果 Function<Integer,Integer> fun5 = x -> x+1; System.out.println(testFunction2("-2",fun4,fun5));// -1 } /* 案例1 : 定义一个方法功能, 根据整数x,计算出对应整数y, x数据由客户给出, y数据的计算方式根据客户要求决定 1)客户1 : y为x的2倍 2)客户2 : y与x相等 3)客户3 : y为x的平方 4)... 参数列表分析: 1. 参数1: 提供int x 2. 参数2: 提供Function<Integer,Integer>, 就是为了提供唯一抽象方法 Integer apply(Integer i) */ public static int testFunction(int x, Function<Integer,Integer> fun){ return fun.apply(x); } /*案例2 : 定义一个方法功能, 根据字符串x,计算出对应整数y, x数据由客户给出, y数据的计算方式根据客户要求决定 1)客户4 : x为”6” , 计算出x转换成整数后, 2倍结果 2)客户5 : x为”-2”, 计算出x转换成整数后, +1的结果 ... 参数列表分析: 1. 参数1 : 提供String x 2. 参数2: 将一个String类型转换成Integer类型,Function<String,Integer>, 为了传递Integer apply(String) 3. 参数3: 将2计算结果,整数的x, 计算出一个整数结果y, Function<Integer,Integer>, 为了传递 Integer apply(Integer) */ public static int testFunction2(String x,Function<String,Integer> fun1, Function<Integer,Integer> fun2){ /*// 将x由制字符串转成成Integer Integer i = fun1.apply(x); // 将Integer的结果计算出需要的y值 Integer i2 = fun2.apply(i); return i2;*/ // andThen方法表示将fun1的apply结果作为fun2函数式接口中方法的参数, andThen方法的返回值结果 // 就是fun2的结果 // 注意: 使用andThen方法功能时候,需要注意, fun1的结果需要与fun2参数类型保持一致 // return fun1.andThen(fun2).apply(x); return fun2.apply(fun1.apply(x)); } }
1、Predicate<T>: 断言型接口
2、抽象方法:boolean test(T t) 判断给定的数据是否符合某个条件
3、作用:
如果需要定义一个函数,接收一个数据,判断数据是否合法,返回一个boolean结果,就可以使用断言型接口,以前我们只能传递过滤好的数据,而现在既可以传递原始数据,也可以传递过滤的条件
4、其他功能:
Predicate and(Predicate pre):在调用者条件判断之后,再由参数条件判断,返回两个条件都满足的判断对象 &&
Predicate or(Predicate pre):返回两个条件任意一个满足的判断对象 ||
Predicate negate():取判断结果的反向结果 !
案例1 :
定义出一个方法, 需要客户提供一个容器ArrayList<Integer>, 根据客户的需求, 将容器中符合条件的数据筛选出来, 将筛选出的数据放置在新容器中返回给客户
1) 客户1 : 要求容器中的所有数, 都能被2整除
2) 客户2 : 要求所有的数据都不大于100
3) 客户3 : 要求所有数据都小于100, 并且都是奇数
4) 客户4 : 要求所有数据或者小于100, 或者是偶数
5) ...
import java.util.ArrayList; import java.util.function.Predicate; public class PredicateInterfaceUse { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(12); list.add(-6); list.add(101); list.add(188); list.add(9); list.add(99); // 1)客户1 : 要求容器中的所有数, 都能被2整除 Predicate<Integer> pre1 = x -> x % 2 == 0; System.out.println(testPredicate(list,pre1));// [12, -6, 188] // 2)客户2 : 要求所有的数据都不大于100 Predicate<Integer> pre2 = x -> x <= 100; System.out.println(testPredicate(list,pre2));// [12, -6, 9, 99] // 3)客户3 : 要求所有数据都小于100, 并且都是奇数 // 使用Predicate接口中的默认方法,negate(), 表示获取的结果是pre1数据结果的取反 Predicate<Integer> pre3 = pre1.negate(); // pre2.and(pre3) : 将pre2的规则与pre3规则做&&运算 System.out.println(testPredicate(list,pre2.and(pre3)));// [9, 99] // 4)客户4 : 要求所有数据或者小于100, 或者是偶数 System.out.println(testPredicate(list,pre2.or(pre1)));// [12, -6, 188, 9, 99] } /*案例1 : 定义出一个方法, 需要客户提供一个容器ArrayList<Integer>, 根据客户的需求, 将容器中符合条件的数据筛选出来, 将筛选出的数据放置在新容器中返回给客户 1)客户1 : 要求容器中的所有数, 都能被2整除 2)客户2 : 要求所有的数据都不大于100 3)客户3 : 要求所有数据都小于100, 并且都是奇数 4)客户4 : 要求所有数据或者小于100, 或者是偶数 5)... 分析方法参数列表: 1. 第一个参数: 需要客户提供ArrayList<Integer> 原始容器 2. 第二个参数: 需要一个对于集合中的数据进行验证的规则, 因此提供Predicate<Integer>,实际上为了 传递boolean test(Integer) */ public static ArrayList<Integer> testPredicate(ArrayList<Integer> list, Predicate<Integer> pre){ ArrayList<Integer> result = new ArrayList<>(); // 1. 遍历提供的list集合,获取出每一个元素 for(Integer i : list){ if(pre.test(i)){ result.add(i); } } return result; } }
1、写一个函数式接口时,方法的实现(lambda体),已经被某个其他的对象实现了,就不需要在Lambda体中,再次实现一遍,而可以直接使用那个已经定义好的方法。
2、格式:
函数式接口 名称 = 对象名 :: 方法名称;
函数式接口 名称 = 类名 :: 静态方法名;
3、作用:
把已经实现的方法,作为一个数据,作为实现类对象,赋值给某个函数式接口的引用
可以把这个引用当做方法的返回值,也可以作为方法的实际参数进行传递
4、本质:
可以把任意一个方法,作为函数式接口的一个实现类对象
public class 方法引用 { public static void main(String[] args) { // 1. 使用lambda表达式实现函数式接口Inter Inter inet = x -> { for(int i = 1; i<= x; i++){ System.out.println(i); } }; inet.print(5); System.out.println("---------------------"); // 2. 因为lambda表达式要实现的lambda体与PrintTest1类中的print方法一样 // 因此可以借用一下PrintTest1类中的print方法, 这就叫这方法引用(使用PrintTest1类中的print方法代替lambda表达式) // 函数式接口 接口名 = 对象::方法名; Inter inet2 = new PrintTest1() :: print; inet2.print(8); System.out.println("+++++++++++++++++++++++"); // 3. 因为lambda表达式要实现的lambda体与PrintTest2中静态方法p一样 // 因此利用方法引用,借用PrintTest2中静态方法p方法道题lambda表达式 // 函数式接口 接口名 = 类名::方法名; Inter inet3 = PrintTest2 :: p; inet3.print(6); // 4. Inter inet4 = x -> System.out.println(x); inet4.print(99); // System.out: 结果是一个PrintStream类型的对象, println就是来自于PrintStream中 Inter inet5 = System.out :: println; } } @FunctionalInterface interface Inter{ public abstract void print(int n); } class PrintTest1{ public void print(int n){ for(int i = 1; i<= n; i++){ System.out.println(i); } } } class PrintTest2{ public static void p(int x){ for(int i = 1; i<= x; i++){ System.out.println(i + "--"); } } }
1、写一个函数式接口时,方法的实现(lambda体),已经被某个其他的对象实现了,就不需要在Lambda体中,再次实现一遍,而可以直接使用那个已经定义好的方法。
2、格式:
函数式接口 名称 = 对象名 :: 方法名称;
函数式接口 名称 = 类名 :: 静态方法名;
3、作用:
把已经实现的方法,作为一个数据,作为实现类对象,赋值给某个函数式接口的引用
可以把这个引用当做方法的返回值,也可以作为方法的实际参数进行传递
4、本质:
可以把任意一个方法,作为函数式接口的一个实现类对象
public class 方法引用 { public static void main(String[] args) { // 1. 使用lambda表达式实现函数式接口Inter Inter inet = x -> { for(int i = 1; i<= x; i++){ System.out.println(i); } }; inet.print(5); System.out.println("---------------------"); // 2. 因为lambda表达式要实现的lambda体与PrintTest1类中的print方法一样 // 因此可以借用一下PrintTest1类中的print方法, 这就叫这方法引用(使用PrintTest1类中的print方法代替lambda表达式) // 函数式接口 接口名 = 对象::方法名; Inter inet2 = new PrintTest1() :: print; inet2.print(8); System.out.println("+++++++++++++++++++++++"); // 3. 因为lambda表达式要实现的lambda体与PrintTest2中静态方法p一样 // 因此利用方法引用,借用PrintTest2中静态方法p方法道题lambda表达式 // 函数式接口 接口名 = 类名::方法名; Inter inet3 = PrintTest2 :: p; inet3.print(6); // 4. Inter inet4 = x -> System.out.println(x); inet4.print(99); // System.out: 结果是一个PrintStream类型的对象, println就是来自于PrintStream中 Inter inet5 = System.out :: println; } } @FunctionalInterface interface Inter{ public abstract void print(int n); } class PrintTest1{ public void print(int n){ for(int i = 1; i<= n; i++){ System.out.println(i); } } } class PrintTest2{ public static void p(int x){ for(int i = 1; i<= x; i++){ System.out.println(i + "--"); } } }