首选大家都知道的是,Lambda表达式可以简洁代码,是JDK1.8新特性,还有就是它是函数式编程,那么我们下面带着问题,就以下几点对lambda表达式进行剖析。
下面给出第一个案例,来看看我们在代码迭代过程中代码进行了怎样的优化和lambda表达式的应用:
现在有一组学生数据,我需要把满足一定年龄的学生,和一定分数的学生的信息分别进行打印
这是个简单的Student类,大家都会建,但是也有小白,我尽量的详细,上面是图片,下面是源代码,可以直接复制运行。
下面是我们的第一版代码:
Student类:
package com.ligong.lambdademo;
/**
一些声明信息
Description:
date: 2021/8/10 10:03
@author luozhao
@since JDK 1.8
*/
public class Student {
private String name;
private int age;
private int score;
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return “Student{” +
“name='” + name + ‘’’ +
“, age=” + age +
“, score=” + score +
‘}’;
}
}
Test类:
package com.ligong.lambdademo;
import java.util.ArrayList;
import java.util.List;
/**
一些声明信息
Description:
date: 2021/8/10 10:05
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) {
ArrayList studentArrayList=new ArrayList();
studentArrayList.add(new Student(“luozhao”,18,67));
studentArrayList.add(new Student(“cao”,12,65));
studentArrayList.add(new Student(“zhangsan”,15,80));
studentArrayList.add(new Student(“lisi”,13,75));
studentArrayList.add(new Student(“xiaoming”,16,95));
System.out.println(“打印年龄大于14岁的孩子信息”);
findGetAge(studentArrayList);
System.out.println(“打印成绩大于70孩子的信息”);
findGetScore(studentArrayList);
}
public static void findGetAge(ArrayList studentArrayList){
ArrayList list=new ArrayList();
for (Student students:studentArrayList
) {
if (students.getAge()>14){
list.add(students);
}
}
for (Student s:list
) {
System.out.println(s);
}
} public static void findGetScore(ArrayList studentArrayList){
ArrayList list=new ArrayList();
for (Student students:studentArrayList
) {
if (students.getScore()>70){
list.add(students);
}
}
for (Student s:list
) {
System.out.println(s);
}
}
}
在上述Test中,我们发现findGetAge,和findGetScore中有很多雷同的地方,
首先,2个方法中,只有if语句的判断条件不同,其他都相同,那么我们怎么样进行迭代呢?
第一首先if方法里面是true,那么我需要让if方法里面为true,看下面这几段代码。
创建一个接口
看到上面代码的迭代你们发现了,有什么不同了?,第一把把遍历集合提取出来了,第二把if判断逻提取了出来,如果不是为了展示lambda特性,其实可以不需要引入接口,可以把Socre和Age放在一个类中写。
迭代版本3,我根本不需要写AgeFilter和ScoreFilter这两个类,我们可以通过匿名内部类的方式进行编写,因为接口只用一次我不需要再创建子类实例啊,对不对宝宝们。
版本3的Test全部代码
package com.ligong.lambda3;
import com.ligong.lambdademo2.AgeFilter;
import com.ligong.lambdademo2.ScoreFilter;
import com.ligong.lambdademo2.Student;
import com.ligong.lambdademo2.StudentFilter;
import java.util.ArrayList;
/**
一些声明信息
Description:
date: 2021/8/10 10:33
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) {
ArrayList studentArrayList=new ArrayList();
studentArrayList.add(new Student(“luozhao”,18,67));
studentArrayList.add(new Student(“cao”,12,65));
studentArrayList.add(new Student(“zhangsan”,15,80));
studentArrayList.add(new Student(“lisi”,13,75));
studentArrayList.add(new Student(“xiaoming”,16,95));
//以下是符合条件的信息
findByStudent(studentArrayList, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getAge()>15;
}
});
System.out.println(“-------------------------------------”);
findByStudent(studentArrayList, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getScore()<80;
}
});
}
public static void findByStudent(ArrayList studentArrayList, StudentFilter filter){
ArrayList list=new ArrayList();
for (Student students:studentArrayList
) {
if (filter.compare(students)){
list.add(students);
}
}
forListStudent(list);
}
public static void forListStudent(ArrayList list){
for (Student s:list
) {
System.out.println(s.toString());
}
}
}
那么,在版本3及之前我们代码都已经简化到这里了,还可以怎样简化呢,下面我们的lambda表达式第一个适用场景出现,
那么就是lambda表达式适用于接口中只有一个抽象方法的接口,例如
多线程里面的Runnable中只有run一个方法,我是不是可以不用实现Runnable接口呢,只用写其匿名内部类,然后实现run的方法体即可。
例如:
下面一段代码和截图是线程方面Lambda的应用,看不懂跳过即可:
package com.ligong.lambdatest;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
一些声明信息
Description:
date: 2021/8/10 12:24
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) throws Exception {
Runnable runnable1=new Runnable() {
@Override
public void run() {
System.out.println(“这是一个Runnable接口的实例1”);
}
};
Thread thread=new Thread(runnable1);
thread.start();
Runnable runnable2=()->{
System.out.println(“这是一个带中括号的lambda接口实例2”);
System.out.println(“愉快的学习,每天都要学一点哦”);
};
runnable2.run();
Runnable runnable3=()-> System.out.println("这是通过lambda表达式的接口实例3");
runnable3.run();
Callable callable=new Callable() {
@Override
public String call() throws Exception {
return "罗兆正在努力的学习java";
}
};
System.out.println(callable.call());
Callable callable1=new Callable() {
@Override
public Integer call() throws Exception {
return 1;
}
};
System.out.println(callable1.call());
Callable callable2=()->true;
System.out.println(callable.call());
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(callable1);
}
}
下面我们给出上述代码中的第4个版本:
Test4代码:
package com.ligong.lambda4;
import com.ligong.lambdademo2.Student;
import com.ligong.lambdademo2.StudentFilter;
import java.util.ArrayList;
/**
一些声明信息
Description:
date: 2021/8/10 10:33
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) {
ArrayList studentArrayList=new ArrayList();
studentArrayList.add(new Student(“luozhao”,18,67));
studentArrayList.add(new Student(“cao”,12,65));
studentArrayList.add(new Student(“zhangsan”,15,80));
studentArrayList.add(new Student(“lisi”,13,75));
studentArrayList.add(new Student(“xiaoming”,16,95));
//以下是符合条件的信息
findByStudent(studentArrayList,(student -> student.getScore()>14) );
System.out.println(“-------------------------------------”);
findByStudent(studentArrayList,student -> student.getAge()>70);
}
public static void findByStudent(ArrayList studentArrayList, StudentFilter filter){
ArrayList list=new ArrayList();
for (Student students:studentArrayList
) {
if (filter.compare(students)){
list.add(students);
}
}
forListStudent(list);
}
public static void forListStudent(ArrayList list){
list.forEach(System.out::println);
看到这里,你会惊喜的发现新大陆一样,原来代码还可以这样写,但是具体原理我自己还不是很清楚,很迫切的需要知道怎样写,是不是,那么下面我给出Lambda表达式的一些介绍及概念性的东西,
你会对上述有了更深的了解
我们知道我开发程序的过程都是一步步演变的,面向过程,面向对象,面向接口,最后面向函数式编程,因为我们知道java是值传递,那么面向函数式编程,可以把我们=号右边入一段代码,或者说是一段逻辑。
下面是一些案例:
Lambda表达式的应用场景,任何有函数式编程的地方
函数式接口
只有一个抽象方法的的接口是函数式接口
这里面我们给出删除2个函数式接口的案例:
代码如下:
package com.ligong.funcationinterface;
import com.sun.org.apache.regexp.internal.RE;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
一些声明信息
Description:
date: 2021/8/10 13:59
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) {
Function
System.out.println( integerFunction.apply(“罗兆正在努力学习?”));
BiFunction biFunction=(a,b)->a.length()+b.length();
System.out.println(biFunction.apply("罗兆", "好帅啊"));
}
}
下面我们快速过渡到
Lambda表达式的方法引用上
一个是带参数的引用,一个是无参的方法引用
2.对象方法引用:
3.静态方法引用:
这个其实是我自定义的函数式接口,像Runnable和Callable等都是函数式接口
这是Runnable接口,且都有FuntionaInterface所标注的都是函数式接口
2.对象方法引用:
代码:
package com.ligong.funcationdemo;
import java.util.function.Consumer;
/**
一些声明信息
Description:
date: 2021/8/10 16:04
@author luozhao
@since JDK 1.8
*/
public class Test {
public static void main(String[] args) {
Consumer c1=(too ->new Too().foo());
c1.accept(new Too());
Consumer c3=(too ->new Too().foo());
c3.accept(new Too());
Consumer c4=Too::foo;
c4.accept(new Too());
}
}
class Too{
public void foo(){
System.out.println(“你好”);
}
有地方可能需要再斟酌一下,感觉有帮助,点赞收藏。