函数式接口:只有一个方法的接口称之为函数式接口 lambda表达式的基础语法: java8引入一个新的操作符"->",该操作符称之为lambda操作符 箭头将lambda表达式分割成两部分 左侧:lambda表达式的参数列表 右侧:lambda表达式需要实现的功能,即lambda体 语法1:无参数,无返回值 () -> System.out.println("hello lambda"); 示例: @Test public void test01(){ //使用匿名内部类方式 Runnable r1=new Runnable() { @Override public void run() { System.out.println("匿名内部类方式..."); } }; r1.run(); System.out.println("-----------------------"); //使用lambda方式 Runnable r2=()-> System.out.println("使用lambda方式"); r2.run(); } 这里需要注意的是:如果在lambda表达式中使用普通的局部变量,或者在匿名内部类中使用普通的局部变量,应该怎么做呢 在jdk1.7之前,该变量必须是final修饰的 示例如下: @Test public void test01() { //使用普通变量number //1.在jdk1.7之前必须使用final修饰,才能在匿名内部类中使用 //2.在jdk1.8之后可以不适用final修饰,但是在底层,已经为我们加上了final修饰,所以在匿名内部类和lambda表达式中 //使用普通变量不能更改其值,如进行number++操作 int number = 0; //使用匿名内部类方式 Runnable r1 = new Runnable() { @Override public void run() { System.out.println("匿名内部类方式..." + number); } }; r1.run(); System.out.println("-----------------------"); //使用lambda方式 Runnable r2 = () -> System.out.println("使用lambda方式" + number); r2.run(); } 语法2:有一个参数,但是无返回值 (x) -> System.out.println(x) 示例: 这里使用Consumer接口,接口代码如下:只有一个方法 @FunctionalInterface public interface Consumer<T> { void accept(T t); } 使用如下: @Test public void test02() { Consumer con = (x) -> {System.out.println(x);}; con.accept("测试lambda表达式"); } 语法3:有一个参数,但是无返回值,这里的小括号可以不写 x -> System.out.println(x) 示例如下: @Test public void test02() { //如果只有一个参数,这里的小括号可以省略 Consumer con = x -> { System.out.println(x); }; con.accept("测试lambda表达式"); } 语法4:有两个以上的参数,并且lambda体中有多条语句,还有返回值 (x,y) -> { 语句1; 语句2; return ...; } 示例: 使用该接口: public interface Comparator<T> { int compare(T o1, T o2); } 示例如下: /** * 有两个以上的参数,并且lambda体中有多条语句,并有返回值 */ @Test public void test03() { //重点1:多个参数 //重点2:多条语句 //重点3:有返回值 Comparator<Integer> com = (x, y) -> { int result = Integer.compare(x, y); return result; }; int result = com.compare(2, 3); System.out.println(result); } 语句5:如果lambda表达式中只有一条语句,则{}和return语句都可以省略不写 示例如下: /** * 测试lambda表达式 * 参数列表有多个参数,并且有返回值,但是lambda方法体只有一句 * 可以省略方法体的{}和retuen */ @Test public void test04() { //lambda方法体中只有一条语句,所以可以省略{}和return Comparator<Integer> com = (x, y) -> Integer.compare(x, y); int result = com.compare(2, 3); System.out.println(result); } 语法6:lambda表达式的参数列表参数类型可以省略不写,因为JVM编辑器通过上下文可以推断出数据类型,即"类型推断" (Integer x,Integer y) ->{Integer.compare(x,y)}; 总结: lambda表达式需要函数式接口的支持 函数式接口:接口中只有一个抽象方法的接口,称之为函数式接口,可以使用注解@FunctionalInterface注解修饰 可以检查是否是函数式接口 ======================================================================= 需求:完成一个数进行任意操作 ======================================================================= 1.写函数式接口:定义一个抽象方法,进行数字运算 @FunctionalInterface public interface MathCalculation<T> { T mathCalculation(T t); } 2.写一个方法,传入参数和该接口:类似于策略模式 //重点1:传入需要计算的参数和接口,调用接口方法并返回 public Integer mathCalculation(int num, MathCalculation<Integer> mathInter) { return mathInter.mathCalculation(num); } 3.测试lambda表达式: @Test public void test5() { //计算一个数的平方 //1.lambda表达式1,有一个参数,有返回,lambda体中只有一个语句,可以省略return和{} int result = mathCalculation(10, (x) -> x * x); System.out.println("10的平方是:" + result); System.out.println("--------------------------------"); //2.一个参数,有返回,并且lambda体中有多个语句 int result2 = mathCalculation(10, (x) -> { int num = x + 1; return num * num; }); System.out.println("10+1的平法是:" + result2); } 场景1:完成小写转换为大写: 1.先定义一个小写转换为大写的接口: @FunctionalInterface public interface ConvertLowToUpperInter { String convertLowToUpper(String lower); } 2.定义一个普通方法:类似于策略模式 /** * 将小写转换为大写的方法 */ 重点1:传入小写的字符串,大小写转换的接口 public String convertLowerToUpper(String lower, ConvertLowToUpperInter convert) { String upper = convert.convertLowToUpper(lower); return upper; } 3.测试: /** * 测试大小写转换 */ @Test public void test6() { String str = "abc"; //重点2:采用lambda表达式的方式,将小写转换为大写 String upper = convertLowerToUpper(str, lower -> lower.toUpperCase()); System.out.println("原始字符串:" + str + " 转换为大写后:" + upper); } 场景2:计算两个long类型的数据并返回long类型: 1.定义一个接口,使用泛型T定义入参,R定义返回 @FunctionalInterface public interface LongCalculation<T,R> { R longCalculation(T t1,T t2); } 2.定义普通方法: /** * 计算两个long类型的数据 * @param t1:计算的入参1 * @param t2:计算的入参2 * @param calculator:用于计算的接口 * @return */ public Long longCalculation(long t1, long t2, LongCalculation<Long, Long> calculator) { long result = calculator.longCalculation(t1, t2); return result; } 3.测试: /** * 测试long类型数据计算 */ @Test public void test7() { long num1 = 10; long num2 = 12; //使用lambda表达式 long result = longCalculation(num1, num2, (x, y) -> x * y); System.out.println(num1 + "*" + num2 + "=" + result); }