函数式编程思想
在此之前都是使用面向对象的编程思想,而该思想强调的是通过对象做事情。例如线程执行任务前必须创建一个实现Runnable接口的对象,但是真正的目的是将run方法的代码给线程对象执行。
而函数式编程思想是省略了创建对象的过程,直接通过lambda表达式传递任务代码给线程对象执行,而不需要创建任务的实现类对象。
函数式编程思想忽略面向对象的复杂语法,强调的是做什么,而不是以什么形式做。
分别使用传递Runnable接口实现类的对象、匿名内部类和Lambda表达式3种方式实现线程的创建
package net.ittimeline.java.core.jdk.feature.java8.lambda;import lombok.extern.log4j.Log4j2;/** * 使用面向对象和函数式编程两种方式创建线程 * * @author tony 18601767221@163.com * @version 2020/12/24 14:48 * @since JDK11 */@Log4j2public class LambdaCreateThreadTest { public static void main(String[] args) { CustomRunnable customRunnable=new CustomRunnable(); Thread thread=new Thread(customRunnable); thread.start(); new Thread(new Runnable() { @Override public void run() { log.info("使用匿名内部类创建线程"); } }).start(); //如果接口中只有一个抽象方法,可以使用lambda表达式 // Runnable表达式就是一个函数式接口,即该接口中只有一个抽象方法 new Thread(()->{ log.info("使用lambda表达式创建线程"); }).start(); }}@Log4j2class CustomRunnable implements Runnable{ @Override public void run() { log.info("使用面向对象编程思想创建线程"); }}
程序运行结果
![9f2cd2258e3a7c54c446159bffd64bc0.png](https://i-blog.csdnimg.cn/blog_migrate/0ece7048a00a65f45d799599467afdd4.jpeg)
Lambda表达式
Lambda表达式的应用场景:如果一个接口中只有一个抽象方法,就可以使用Lambda表达式替换该接口的实现类对象。
Lambda表达式的标准格式由三部分组成
- (参数类型 参数名,参数类型 参数名),()和函数式接口中的抽象方法的参数列表一致,即参数的个数和顺序一致。参数类型可以省略,如果()中只有一个参数,()和参数类型可以一起省略
- 箭头 (->) 是固定写法,表示指向
- 代码块 {} 抽象方法的需要执行的代码,如果代码块中只有一行代码,那么{}、return和;可以一起省略。代码块在调用该接口的抽象方法后执行。
使用lambda表达式给集合的元素排序
package net.ittimeline.java.core.jdk.feature.java8.lambda;import lombok.extern.log4j.Log4j2;import java.util.*;/** * 使用lambda给集合元素排序 * * @author tony 18601767221@163.com * @version 2020/12/24 15:30 * @since JDK11 */@Log4j2public class LambdaCollectionsSortTest { public static void main(String[] args) { List data=new ArrayList<>(); data.add(100); data.add(200); data.add(400); data.add(500); data.add(700); data.add(800); data.add(900); data.add(600); data.add(300); //使用匿名内部类排序 Collections.sort(data, new Comparator() { @Override public int compare(Integer o1, Integer o2) { return o2-o1; } }); log.info("使用匿名内部类降序排序{}",data); /** * 使用lambda表达式排序 */ Collections.sort(data,(Integer o1,Integer o2)->{ return o2-o1; }); log.info("使用Lambda表达式降序排序{}",data); }}
程序运行结果
![6d96846301cbd40ef088bf1d6fa9be93.png](https://i-blog.csdnimg.cn/blog_migrate/c5b8dccf5d897eb456f385431926d19b.jpeg)
lambda表达式
/** * 使用lambda表达式排序 */ Collections.sort(data,(Integer o1,Integer o2)->{ return o2-o1; });
可以把参数类型,return以及{}省略
/** 使用lambda表达式排序 */ Collections.sort(data, (o1, o2) -> o2 - o1);
使用Lambda表达式的前提条件必须具有接口,例如之前使用的Runnable,Comparator,而且接口中只能有一个抽象方法。这种接口被称为函数式接口,函数式接口使用@FunctionalInterface注解标识。
![ca847c72d4ec91c1bad6e17b6a75aecf.png](https://i-blog.csdnimg.cn/blog_migrate/140f6e5921b6cbe49a3e77ad762b78bb.jpeg)
但是接口中可以有别的方法
![d6a3239c3bbe0b0b683211331649268b.png](https://i-blog.csdnimg.cn/blog_migrate/0f65fe3d5ecb5a7ac1f8e04a28ff6fbb.jpeg)
根据Lambda表达式可以推理出接口中的抽象方法,根据抽象方法也可以推出Lambda表达式。
自定义函数式接口CustomFunctionInterface
package net.ittimeline.java.core.jdk.feature.java8.lambda;/** * 自定义函数式接口 * * @author tony 18601767221@163.com * @version 2020/12/24 16:46 * @since JDK11 */@FunctionalInterfacepublic interface CustomFunctionInterface { int add(int left,int right);}
Lambda表达式的表现形式有如下三种:变量,方法的形参,方法的返回值
- 变量表现形式
package net.ittimeline.java.core.jdk.feature.java8.lambda;import lombok.extern.log4j.Log4j2;import java.util.*;/** * lambda表达式的三种形式 * * @author tony 18601767221@163.com * @version 2020/12/24 16:55 * @since JDK11 */@Log4j2public class LambdaExpressionVariableTest { public static void main(String[] args) { // 形式1 变量表现形式 Runnable runnable = () -> { log.info("变量的形式使用lambda表达式"); }; Thread thread = new Thread(runnable); thread.start(); Comparator comparator = (o1, o2) -> o1 - o2; List data= Arrays.asList(1,2,4,5,7,8,9,6,3); Collections.sort(data,comparator); CustomFunctionInterface customFunctionInterface = (left, right) -> { log.info("left = {}", left); log.info("right = {}", right); int result = left + right; log.info("result = {}", result); return result; }; //lambda表达式的代码块在方法调用后执行 customFunctionInterface.add(10,20);}}
程序运行结果
- 方法的形参的表现形式
package net.ittimeline.java.core.jdk.feature.java8.lambda;import lombok.extern.log4j.Log4j2;import java.util.Arrays;import java.util.Collections;import java.util.List;/** * lambda表达式的表现形式-形参 * * @author tony 18601767221@163.com * @version 2020/12/24 17:44 * @since JDK11 */@Log4j2public class LambdaExpressionFunctionArgsTest { public static void main(String[] args) { // Lambda表达式作为形参 new Thread(()->{log.info("lambda表达式作为构造器的形参");}).start(); List data= Arrays.asList(1,2,4,5,7,8,9,6,3); Collections.sort(data,(o1,o2)->o1-o2); log.info("data集合排序后的结果是{}",data); int x=10; int y=20; //lambda表达式的代码块只有在调用接口的方法后才会执行 add((left,right)-> { log.info("left = {}", left); log.info("right = {}", right); int result = left + right; log.info("result = {}", result); return result; },x,y); } public static void add(CustomFunctionInterface customFunctionInterface,int x,int y){ customFunctionInterface.add(x,y); }}
程序运行结果
![96635d48288df9d78dee951e7d8dd5be.png](https://i-blog.csdnimg.cn/blog_migrate/60e0352c045274f4933e4ae440da2b02.jpeg)
- 方法的返回值的表现形式
package net.ittimeline.java.core.jdk.feature.java8.lambda;import lombok.extern.log4j.Log4j2;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;/** * lambda表达式的表现形式-返回值 * * @author tony 18601767221@163.com * @version 2020/12/24 17:47 * @since JDK11 */@Log4j2public class LambdaExpressionFunctionReturnValueTest { public static void main(String[] args) { // lambda表达式作为方法的返回值 Runnable runnable=getRunnable(); new Thread(runnable).start(); List data= Arrays.asList(1,2,4,5,7,8,9,6,3); Collections.sort(data,getComparator()); log.info("data集合排序后的结果是{}",data); CustomFunctionInterface customFunctionInterface=getCustomFunctionInterface(); int result = customFunctionInterface.add(10, 20); log.info("result = {}",result); } /** * // 形式3 返回值 * lambda 表达式在方法返回值的应用 * @return */ public static Runnable getRunnable(){ return ()->{ log.info("lambda表达式作为方法的返回值"); }; } /** * lambda表达式作为方法的返回值 * @return */ public static Comparator getComparator(){ return (o1,o2)->o1-o2; } public static CustomFunctionInterface getCustomFunctionInterface(){ return (o1,o2)->o1+o2; }}
程序运行结果
![cb03d25eafa9a104ee84dc29a2e42713.png](https://i-blog.csdnimg.cn/blog_migrate/0dadcbccb3164898993b3ef6a1bf60f7.jpeg)