lambda表达式

  • Lambda表达式是 Java8 中最重要的新功能之一。使用 Lambda 表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。

先看一个例子

import java.util.*;

public class lambdaDemo {

    public static void main(String[] args) {
        //普通实现
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("running");
//            }
//        });
//        thread.start();
        //lambda表达式写法
//        new Thread(()->{System.out.println("running2...");}).start();


        //普通写法
        List<String> list = Arrays.asList("java","c","c++","pyhton");
//        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);
//        }
        //lambda表达式写法
        Collections.sort(list, (a,b)->a.length()-b.length());
        list.forEach(System.out::println);
    }
}

函数式接口

只有一个抽象方法(Object 类中的方法除外)的接口是函数式接口

常用接口

Supplier 代表一个输出
Consumer 代表一个输入
BiConsumer 代表两个输入
Function 代表一个输入,一个输出(一般输入和输出是不同类型的)
UnaryOperator 代表一个输入,一个输出(输入和输出是相同类型的)
BiFunction 代表两个输入,一个输出(一般输入和输出是不同类型的)
BinaryOperator 代表两个输入,一个输出(输入和输出是相同类型的)

方法的引用

▪ 方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用

lambda表达式java if lambda表达式java循环_java

▪ 静态方法引用:如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用

import java.util.function.Supplier;

public class Test2 {

    static String put(){
        System.out.println("put...");
        return "put";
    }

    public static void main(String[] args) {
        Supplier<String> s1 = ()->Test2.put();
        System.out.println(s1.get());

        Supplier<String> s2 = Test2::put;
        System.out.println(s2.get());

        Supplier<String> s3 = Fun::hehe;
        System.out.println(s3.get());
    }
}

class Fun{
    public static String hehe(){
        return "hehe";
    }
}

▪ 实例方法引用:如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class Test3 {

    public String put(){
        return "put...";
    }

    public void getSize(int size){
        System.out.println(size);
    }

    public String toUpperCase(String str){
        return str.toUpperCase();
    }

    public static void main(String[] args) {
        Supplier<String> s1 = ()->new Test3().put();
        Supplier<String> s2 = ()->{return new Test3().put();};
        Supplier<String> s3 = new Test3()::put;
        System.out.println(s1.get()+s2.get()+s3.get());

        Test3 test3 = new Test3();
        Consumer<Integer> c1 = (size)->test3.getSize(size);
        Consumer<Integer> c2 = test3::getSize;
        c1.accept(123);
        c2.accept(456);

        Function<String,String> f1 = (str)->str.toUpperCase();
        Function<String,String> f2 = (str)->test3.toUpperCase(str);
        Function<String,String> f3 = new Test3()::toUpperCase;
        Function<String,String> f4 = test3::toUpperCase;
        System.out.println(f1.apply("abc")+f2.apply("abc")+f3.apply("abc")+f4.apply("abc"));
    }
}

▪ 对象方法引用:抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用

import java.util.function.Consumer;

public class Test4 {
    public static void main(String[] args) {
        Consumer<Tool> c1 = (Tool tool) -> new Tool().foo();
        c1.accept(new Tool());
        Consumer<Tool> c2 = (Tool tool) -> new Tool2().foo2();
        c2.accept(new Tool());
        Consumer<Tool> c3 = Tool::foo;
        c3.accept(new Tool());
    }
}

class Tool{
    public Integer fun(String s){
        return 1;
    }

    public void foo(){
        System.out.println("foo");
    }
}

class Tool2{
    public Integer fun2(String s){
        return 1;
    }

    public void foo2(){
        System.out.println("foo---foo2");
    }
}

▪ 构造方法引用:如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用

import java.util.function.Consumer;
import java.util.function.Supplier;

public class Test5 {
    public static void main(String[] args) {
        Supplier<Person> s1 = ()->new Person();
        s1.get();
        Supplier<Person> s2 = Person::new;
        s2.get();

        Consumer<Integer> c1 = (age)->{new Account(age);};
        Consumer<Integer> c2 = Account::new;
        c1.accept(123);
        c2.accept(456);
    }
}

class Account{
    public Account(){
        System.out.println("调用无参构造方法");
    }

    public Account(int age){
        System.out.println("age.构造参数"+age);
    }

    public Account(String str){
        System.out.println("String 构造参数"+str);
    }
}

class Person{
    public Person(){
        System.out.println("调用无参的构造方法");
    }
}
ntln("age.构造参数"+age);
    }

    public Account(String str){
        System.out.println("String 构造参数"+str);
    }
}

class Person{
    public Person(){
        System.out.println("调用无参的构造方法");
    }
}