Lambda表达式的介绍
Lambda表达式是 Java8 中最重要的新功能之一。使用 Lambda 表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。
Lambda表达式的特点
- Lambda表达式的使用
1:函数式编程
2:参数类型自动推断
3:代码量少,简洁 - Lambda表达式案例
- Lambda表达式应用场景
任何有函数式接口的地方
函数式接口
只有一个抽象方法(Object类中的方法除外)的接口是函数式接口
Supplier 代表一个输出
Consumer 代表一个输入
BiConsumer 代表两个输入
Function 代表一个输入,一个输出(一般输入和输出是不同类型的)
UnaryOperator 代表一个输入,一个输出(输入和输出是相同类型的)
BiFunction 代表两个输入,一个输出(一般输入和输出是不同类型的)
BinaryOperator 代表两个输入,一个输出(输入和输出是相同类型的)
方法的引用
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用
- 方法引用的分类
静态方法引用:如果函数式接口的实现恰好可以通过调用一个静 态方法来实现,那么就可以使用静态方法引用
实例方法引用:如果函数式接口的实现恰好可以通过调用一个实 例的实例方法来实现,那么就可以使用实例方法引用
对象方法引用:抽象方法的第一个参数类型刚好是实例方法的类 型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函 数式接口的实现能由上面说的实例方法调用来实现的话,那么就 可以使用对象方法引用
构造方法引用:如果函数式接口的实现恰好可以通过调用一个类 的构造方法来实现,那么就可以使用构造方法引用
函数式接口
@FunctionalInterface //可以用来判断只有一个方法,注解,当前方法是函数式接口
//函数式接口:有且仅有一个抽象方法的接口
public interface InterfaceTest {
public void add();
//public void sub();加了这个就有两个抽象方法 就会报错
}
lambda
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author Petrel
* @data 2020/7/1 13:39
*/
public class LambdaDemo {
public static void main(String[] args) {
//原本的
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("running......"); //运行结果:running......
}
});
thread.start();
//有了lambda之后
new Thread(()->{
System.out.println("running1......");//运行结果:running1......
}).start();
List<String> list = Arrays.asList("java","javascript","scala","python");
//原本的按长度排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
for (String str:list){
System.out.println(str);//运行结果:java scala python javascript
}
//有了lambda之后
Collections.sort(list,(a,b)->a.length()-b.length());
list.forEach(System.out::println);//运行结果:java scala python javascript
}
}
jdk1.8为什么引入lambda
package why;
/**
* @author Petrel
* @data 2020/7/1 15:07
*/
public class Student {
private String name;
private int age;
private int score;
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
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 +
'}';
}
}
------------
package why;
import java.util.ArrayList;
/**
* @author Petrel
* @data 2020/7/1 15:05
*/
//为什么jdk1.8引入lambda
// why有很多重复代码
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
//查找年龄大于14的学生
findByAge(list);
//查找分数大于75的学生
findByScore(list);
}
//下面两段有很多重复代码
public static void findByAge(ArrayList<Student> students){
ArrayList<Student> list = new ArrayList<>();
for (Student stu:students){
if (stu.getAge()>14){
list.add(stu);
}
}
for (Student student:list){
System.out.println("年龄大于14的学生:"+student);
}
}
public static void findByScore(ArrayList<Student> students){
ArrayList<Student> list = new ArrayList<>();
for (Student stu:students){
if (stu.getScore()>75){
list.add(stu);
}
}
for (Student student:list){
System.out.println("分数大于75的学生:"+student);
}
}
}
package why2;
import why.Student;
public interface StudentFilter {
boolean compare(Student student);
}
------------
package why2;
import why.Student;
/**
* @author Petrel
* @data 2020/7/1 15:27
*/
public class AgeFilter implements StudentFilter {
@Override
public boolean compare(Student student) {
return student.getAge()>14;
}
}
------------
package why2;
import why.Student;
/**
* @author Petrel
* @data 2020/7/1 15:28
*/
public class ScoreFilter implements StudentFilter {
@Override
public boolean compare(Student student) {
return student.getScore()>75;
}
}
------------
package why2;
import why.Student;
import java.util.ArrayList;
/**
* @author Petrel
* @data 2020/7/1 15:29
*/
//why的进阶版。但是如果要比较名字长度还要创建子类
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
getByFilter(list,new AgeFilter());
getByFilter(list,new ScoreFilter());
}
public static void getByFilter(ArrayList<Student> students,StudentFilter filter){
ArrayList<Student> list = new ArrayList<>();
for (Student student:students){
if (filter.compare(student)){
list.add(student);
}
}
printStudent(list);
}
public static void printStudent(ArrayList<Student> students){
for (Student student:students);
}
}
package why3;
import why.Student;
import why2.StudentFilter;
import java.util.ArrayList;
/**
* @author Petrel
* @data 2020/7/1 15:36
*/
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
getByFilter(list, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getAge()>14;
}
});
//why4进阶到getByFilter(list,(e)->e.getAge()>14 );
getByFilter(list, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getScore()>75;
}
});
System.out.println("-------------------");
getByFilter(list, new StudentFilter() {
@Override
public boolean compare(Student student) {
return student.getName().length()>5;
}
});
}
public static void getByFilter(ArrayList<Student> students, StudentFilter filter){
ArrayList<Student> list = new ArrayList<>();
for(Student student:students){
if(filter.compare(student)){
list.add(student);
}
}
printStudent(list);
}
public static void printStudent(ArrayList<Student> students){
for(Student student:students){
System.out.println(student);
}
}
}
package why4;
import why.Student;
import why2.StudentFilter;
import java.util.ArrayList;
/**
* @author Petrel
* @data 2020/7/1 15:36
*/
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",14,67));
list.add(new Student("lisi",13,89));
list.add(new Student("wangwu",15,97));
list.add(new Student("maliu",12,63));
list.add(new Student("zhaoqi",17,75));
getByFilter(list,(e)->e.getAge()>14 );
getByFilter(list, (e)->e.getScore()>75);
System.out.println("-------------------");
getByFilter(list, (e)->e.getName().length()>5);
}
public static void getByFilter(ArrayList<Student> students, StudentFilter filter){
ArrayList<Student> list = new ArrayList<>();
for(Student student:students){
if(filter.compare(student)){
list.add(student);
}
}
printStudent(list);
}
public static void printStudent(ArrayList<Student> students){
for(Student student:students){
System.out.println(student);
}
}
}
Lambda表达式应用在任何有函数式接口的地方
package lambda;
public interface LambdaInterface {
int get();
}
------------
package lambda;
import why.Student;
import java.util.concurrent.Callable;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author Petrel
* @data 2020/7/1 16:18
*/
public class LambdaTest {
public static void main(String[] args) throws Exception {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("running1...");//运行结果:running1...
}
};
runnable.run();
Runnable runnable2 = ()->{
System.out.println("running2...");//运行结果:running2...
};
runnable2.run();
Runnable runnable3 = ()-> System.out.println("running3...");//运行结果:running3...
runnable3.run();
Callable<String> c1 = new Callable() {
@Override
public String call() throws Exception {
return "miffy";
}
};
System.out.println(c1.call());//运行结果:miffy
Callable<String> c2 = ()->{return "miffy2";};
System.out.println(c2.call());//运行结果:miffy2
Callable<String> c3 = ()->"miffy3";//运行结果:miffy3
System.out.println(c3.call());
StudentDao sd1 = new StudentDao() {
@Override
public void insert(Student student) {
System.out.println("插入学生1");//运行结果:插入学生1
}
};
sd1.insert(new Student());
StudentDao sd2 = (student)->{
System.out.println("student:"+student);//运行结果:student:student{name='null', age=0, score=0}
};
sd2.insert(new Student());
StudentDao sd3 = (Student student)-> System.out.println("student3:"+student);//运行结果:student3:student{name='null', age=0, score=0}
sd3.insert(new Student());
TeacherDao td1 = new TeacherDao() {
@Override
public int get(Teacher teacher) {
return 1;
}
};
TeacherDao td2 = (teacher)->{return 2;};
TeacherDao td3 = (Teacher teacher)->{return 3;};
TeacherDao td4 = (teacher)->4;
TeacherDao td5 = (Teacher teacher)->5;
System.out.println(td1.get(new Teacher()));//运行结果:1
System.out.println(td2.get(new Teacher()));//运行结果:2
System.out.println(td3.get(new Teacher()));//运行结果:3
System.out.println(td4.get(new Teacher()));//运行结果:4
System.out.println(td5.get(new Teacher()));//运行结果:5
/*
* 在Java中提供了一系列的函数式接口,用来接受后续传入的逻辑,但是对输入和输出有要求
* */
//Function 代表一个输入,一个输出(一般输入和输出是不同类型的)
Function<String,Integer> f1 = (str)->{return str.length();};
System.out.println(f1.apply("abcd"));//运行结果:4
//Supplier 代表一个输出
Supplier<String> s1 = ()->{return "miffy";};
Supplier<String> s2 = ()->"miffy";
System.out.println(s1.get());//运行结果:miffy
System.out.println(s2.get());//运行结果:miffy
//Consumer 代表一个输入
Consumer<String> c11 = (str)-> System.out.println(str);
c11.accept("miffy");//运行结果:miffy
//BiConsumer 代表两个输入
BiFunction<String,String,Integer> bf = (a,b)->a.length()+b.length();
System.out.println(bf.apply("Miffy", "cute"));//运行结果:9
Runnable runnable1 = ()->{int i = get();//这里相当于是get方法,所以可以有返回值
System.out.println(i);};
Runnable runnable4 = ()->exec();
//Runnable runnable5 = ()->100; 这样写回报错 因为Runnable没有返回值
runnable1.run();
LambdaInterface li1 = ()->get();
//LambdaInterface li2 = ()-find(); 这样会报错,因为LambdaInterface接口中定义的是int类型
LambdaInterface li3 = ()->100;
//LambdaInterface li4 = ()->"abc";这样会报错,因为LambdaInterface接口中定义的是int类型
LambdaInterface li5 = ()->true?1:0;
System.out.println(li1.get());//运行结果:1
}
static int get(){
return 1;
}
static String find(){
return "find";
}
static void exec(){
find();
}
}
package lambda;
import why.Student;
@FunctionalInterface
public interface StudentDao {
void insert(Student student);
}
------------
package lambda;
/**
* @author Petrel
* @data 2020/7/1 16:47
*/
public class Student {
}
package lambda;
/**
* @author Petrel
* @data 2020/7/1 16:53
*/
@FunctionalInterface
public interface TeacherDao {
int get(Teacher teacher);
}
------------
package lambda;
/**
* @author Petrel
* @data 2020/7/1 17:30
*/
public class Teacher {
}
Lambda表达式的语法
package functionrel;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* @author Petrel
* @data 2020/7/2 13:28
*/
public class Test1 {
public static void main(String[] args) {
Function<String,Integer> f1 = (str)->{return str.length();};
System.out.println(f1.apply("miffy"));//运行结果:5
Consumer<String> c = (str)-> System.out.println(str);
c.accept("str");//运行结果:str
}
}
package functionrel;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author Petrel
* @data 2020/7/2 13:37
*/
//静态方法引用
public class Test2 {
static String put(){
System.out.println("put...");
return "put";
}
public static void getSize(int size){
System.out.println(size);
}
public static String toUpperCase(String str){
return str.toUpperCase();
}
public static Integer getLength(String str,String str2){
return str.length()+str2.length();
}
public static void main(String[] args) {
System.out.println(put()); //运行结果:put... put
Supplier<String> s1 = ()->Test2.put();
System.out.println(s1.get());//运行结果:put... put
Supplier<String> s2 = Test2::put;
System.out.println(s2.get());//运行结果:put... put
Supplier<String> s3 = Fun::hehe;
System.out.println(s3.get());//运行结果:hehe
Consumer<Integer> c1 = (size)->Test2.getSize(size);
Consumer<Integer> c2 = Test2::getSize;
c1.accept(123);//运行结果:123
c2.accept(456);//运行结果:456
Function<String,String> f1 = (str)->str.toUpperCase();
Function<String,String> f2 = (str)->Test2.toUpperCase(str);
Function<String,String> f3 = Test2::toUpperCase;
Function<String,String> f4 = Fun::toUpperCase;
System.out.println(f1.apply("abc"));//运行结果:ABC
System.out.println(f2.apply("abc"));//运行结果:ABC
System.out.println(f3.apply("abc"));//运行结果:ABC
System.out.println(f4.apply("abc"));//运行结果:ABC
//BiFunction 代表两个输入,一个输出
BiFunction<String,String,Integer> bf = (a,b)->a.length()+b.length();
BiFunction<String,String,Integer> bf2 = Test2::getLength;
System.out.println(bf.apply("abc", "def"));//运行结果:6
System.out.println(bf2.apply("ghi", "jkl"));//运行结果:6
}
}
class Fun{
public static String hehe(){
return "hehe";
}
public static String toUpperCase(String str){
return str.toUpperCase();
}
}
package functionrel;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author Petrel
* @data 2020/7/2 15:32
*/
//实例方法引用
public class Test3 {
public String put(){
return "put...";
}
public void getSize(int size){
System.out.println("size:" + size);
}
public String toUpperCase(String str){
return str.toUpperCase();
}
public static void main(String[] args) {
System.out.println(new Test3().put());
Supplier<String> s1 = ()->new Test3().put();
Supplier<String> s2 = ()->{return new Test3().put();};
Supplier<String> s3 = new Test3()::put;
System.out.println(s1.get());
System.out.println(s2.get());
System.out.println(s3.get());
//唯一的创建一个test3对象
Test3 test = new Test3();
Consumer<Integer> c1 = (size)->new Test3().getSize(size);
Consumer<Integer> c2 = new Test3()::getSize;
Consumer<Integer> c3 = test::getSize;
c1.accept(123);
c2.accept(456);
c3.accept(789);
Function<String,String> f1 = (str)->str.toUpperCase();
Function<String,String> f2 = (str)->test.toUpperCase(str);
Function<String,String> f3 = new Test3()::toUpperCase;
Function<String,String> f4 = test::toUpperCase;
System.out.println(f1.apply("abc"));
System.out.println(f2.apply("abc"));
System.out.println(f3.apply("abc"));
System.out.println(f4.apply("abc"));
}
}
package functionrel;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
/**
* @author Petrel
* @data 2020/7/2 16:36
*/
//对象方法引用
public class Test4 {
public static void main(String[] args) {
Consumer<Too> c1 = (too)->new Too().foo();
c1.accept(new Too());
Consumer<Too> c2 = (Too too)->new Too2().foo(); //后面传什么对象无所谓 但是前面的泛型Too要一致
c2.accept(new Too());
Consumer<Too> c3 = Too::foo;
c3.accept(new Too());
BiConsumer<Too2,String> bc = (too2,str) ->new Too2().show(str);
BiConsumer<Too2,String> bc2 = Too2::show;
bc.accept(new Too2(),"abc");
bc2.accept(new Too2(),"def");
BiFunction<Exec,String,Integer> bf1 = (e,s)->new Exec().test(s);
bf1.apply(new Exec(),"abc");
BiFunction<Exec,String,Integer> bf2 = Exec::test;
bf2.apply(new Exec(),"sac");
}
}
class Exec{
public int test(String name){
return 1;
}
}
class Too{
public Integer fun(String s){
return 1;
}
public void foo(){
System.out.println("foo");
}
}
class Too2{
public Integer fun(String s){
return 1;
}
public void foo(){
System.out.println("foo--too2");
}
public void show(String str){
System.out.println("show ---too2"+str);
}
}
package functionrel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @author Petrel
* @data 2020/7/2 17:29
*/
//构造方法的引用
public class Test5 {
public static void main(String[] args) {
Supplier<Person> s1 = ()->new Person();
s1.get();
Supplier<Person> s2 = Person::new;
s2.get();
Supplier<List> s3 = ArrayList::new;
Supplier<Set> s4 = HashSet::new;
Supplier<Thread> s5 = Thread::new;
Supplier<String> s6 = String::new;
//Supplier<Integer> s7 = Integer::new; 会报错
Consumer<Integer> c1 = (age)->new Account(age);
Consumer<Integer> c2 = Account::new;
c1.accept(123);
c2.accept(456);
Function<String,Account> f1 = (str)->new Account(str);
Function<String,Account> f2 = Account::new;
f1.apply("abc");
f2.apply("adf");
}
}
class Account{
public Account(){
System.out.println("调用无参构造方法");
}
public Account(int age){
System.out.println("age 参数构造" +age);
}
public Account(String str){
System.out.println("str 参数构造" +str);
}
}
class Person{
public Person(){
System.out.println("调用无参的构造方法");
}
}