Java-Lambda

Lambda是什么

Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性,Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中),使用 Lambda 表达式可以使代码变的更加简洁紧凑。
Lambda是一个匿名函数

        ()->{}
        ():描述参数列表;{}:用来描述方法体
        ->:lambda运算符,称作 goes to

函数式接口

说到Lambda就不得不说函数式接口
什么是函数式接口?

  • 只包含一个抽象方法的接口,称为函数式接口。
  • 可以通过Lambda表达式来创建该接口的对象(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)
  • 在Java8后可以在任意函数式接口上使用@FunctionalInterface注解,其主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。
@FunctionalInterface
public interface LambdaNoneReturnMutipleParm {
    void test(int a,int b);
}

Lambda的使用条件

从以上能够看出,Lambda的使用条件是接口中有且只有一个必须实现的方法,如果有一个以上,Lambda就不知道该实现那个方法,在java8中新增了接口的默认方法,Lambda不受其影响
在这里插入图片描述
默认方法:

@FunctionalInterface
public interface LambdaNoneReturnMutipleParm {
    void test(int a,int b);
    default void test(){
        System.out.println("默认方法");
    }
}

Lambda的使用

先创建六个接口来分别测试

@FunctionalInterface
public interface LambdaNoneReturnMutipleParm {
    void test(int a,int b);
    default void test(){
        System.out.println("默认方法");
    }
}
-----
@FunctionalInterface
public interface LambdaNoneReturnNoneParm {
    void test();
}
-----
@FunctionalInterface
public interface LambdaNoneReturnSingleParm {
    void test(int a);
}
-----
@FunctionalInterface
public interface LambdaSingleReturnMutipleParm {
    int test(int a,int b);
}
-----
@FunctionalInterface
public interface LambdaSingleReturnNoneParm {
    int test();
}
-----
@FunctionalInterface
public interface LambdaSingleReturnSingleParm {
    int test(int a);
}

Lambda表达式的基础语法

 //1.Lambda表达式的基础语法
        //无参无返回
        LambdaNoneReturnNoneParm lambda1 = ()->{
            System.out.println("LambdaNoneReturnNoneParm");
        };
        lambda1.test();
        //单个参数,无返回
        LambdaNoneReturnSingleParm lambda2 = (int a)->{
            System.out.println("LambdaNoneReturnSingleParm: "+a);
        };
        lambda2.test(77);
        //多个参数,无返回
        LambdaNoneReturnMutipleParm lambda3 = (int a,int b)->{
            System.out.println("LambdaNoneReturnMutipleParm:  a:"+a+",b: "+b+",a+b: "+(a+b));
        };
        lambda3.test(10,77 );
        //无参,有返回
        LambdaSingleReturnNoneParm lambda4 = ()->{
            return 77;
        };
        int ret = lambda4.test();
        System.out.println(ret);
        //单个参数,有返回
        LambdaSingleReturnSingleParm lambda5 = (int a)->{
            return a*10;
        };
        int ret2 = lambda5.test(7);
        System.out.println(ret2);
        //多个参数,有返回
        LambdaSingleReturnMutipleParm lambda6 = (int a,int b)->{
            return a*b;
        };
        int ret3 = lambda6.test(7,11);
        System.out.println(ret3);

Lambda语法精简

  • 参数类型,由于已经在接口的抽象方法中,已经定义了参数的数量和类型,所以在表达式中,参数的类型可以省略(参数类型要么都省略,要么都不省略,不能只省略其中一个)
//多个参数,无返回
 LambdaNoneReturnMutipleParm lambda = (a,b)->{
            System.out.println("LambdaNoneReturnMutipleParm:  a:"+a+",b: "+b+",a+b: "+(a+b));
        };
        lambda.test(10,77 );
  • 参数小括号,如果参数的数量只要一个,小括号可以省略
//单个参数,无返回
        LambdaNoneReturnSingleParm lambda2 = a->{
            System.out.println("LambdaNoneReturnSingleParm: "+a);
        };
        lambda2.test(77);
  • 方法大括号,如果方法体中只有一条语句,大括号可以省略
//无参无返回
       LambdaNoneReturnNoneParm lambda3 = ()-> System.out.println("LambdaNoneReturnNoneParm");
       lambda3.test();
  • 如果方法体中,唯一的一条语句是返回语句,在省略大括号的同时必须省略掉return
 LambdaSingleReturnNoneParm lambda4 = ()-> 77;
       int ret = lambda4.test();
       System.out.println(ret);

lambda语法进阶

  • 方法引用:可以快速的将一个lambda表达式的实现指向一个已经实现的方法
    语法;方法的属于者::方法名
    参数类型和数量要和接口中的方法一致,返回值也一样

静态方法引用:

public class syntax3 {
    public static void main(String[] args) {
        //lambda语法进阶
        //方法引用:可以快速的将一个lambda表达式的实现指向一个已经实现的方法
        //语法,方法的属于者::方法名
        //参数类型和数量要和接口中的方法一致,返回值也一样
//        LambdaSingleReturnSingleParm lambda1 = a -> a*2;
//        LambdaSingleReturnSingleParm lambda2 = a -> a*2;
        LambdaSingleReturnSingleParm lambda1 = a -> change(a);
        int ret = lambda1.test(2);
        System.out.println("ret: "+ret);
        //方法引用
        LambdaSingleReturnSingleParm lambda2 = syntax3::change;
        int ret2 = lambda2.test(2);
        System.out.println("ret2: "+ret2);
    }
    private static int change(int a){
        return a*2;
    }
}

构造方法的引用:

先定义一个Person类

public class Person {
  private String name;
  private int age;

  @Override
  public String toString() {
      return "Person{" +
              "name='" + name + '\'' +
              ", age=" + age +
              '}';
  }

  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 Person() {
      System.out.println("无参构造器");
  }

  public Person(String name, int age) {
      this.name = name;
      this.age = age;
      System.out.println("有参构造器: "+name+",age: "+age);
  }
}

        PersonCreater creater = ()->new Person();//一般的Lambda用法
         Person a = creater.getPerson();
        //无参构造方法的引用
        PersonCreater creater1 = Person::new;//构造方法引用      
        Person b =creater1.getPerson();
        //多个参数构造方法引用
        PersonCreaterWithParm creater2 = Person::new;
        Person c = creater2.getPerson("林北",21 );

-----
@FunctionalInterface
interface PersonCreater{
    Person getPerson();
}
@FunctionalInterface
interface PersonCreaterWithParm{
    Person getPerson(String name,int age);
}


Java四大核心函数式接口

在使用Lambda表达式的时候总要自己写函数式接口吗? 当然不是这样了,Java8里面提供了四大核心的函数式供我们使用

函数式接口 参数类型 返回类型 作用
Consumer T void 对类型T参数操作,无返回结果,包含方法 void accept(T t)
Supplier T 返回T类型参数,方法时 T get()
Function T R 对类型T参数操作,返回R类型参数,包含方法 R apply(T t)
Predicate T Boolean 断言型接口,对类型T进行条件筛选操作,返回boolean,包含方法 boolean test(T t)

使用

 /**
     * Consumer<T>
     */
    @Test
    public void ConsumerTest(){
        consumer("Consumer",(m)-> System.out.println("我是ConsumerTest接口:"+m) );
    }
    public void consumer(String name, Consumer consumer){
        consumer.accept(name);
    }

    /**
     * Supplier<T>
     */
    @Test
    public void SupplierTest() {
        List<Integer> list = getNumList(7,()->(int)Math.random()*8);
        list.forEach(System.out::println);
    }
    public List<Integer> getNumList(int n, Supplier<Integer> supplier){
        List<Integer> list = new ArrayList<>();
        for(int i = 0;i<n;i++){
            Integer num = supplier.get();
            list.add(num);
        }
        return list;
    }

    /**
     * Function<T,R>
     */
    @Test
    public  void FunctionTest(){
        String str=strHandle("Hello World",(string)->string.substring(2,5 ));
        System.out.println(str);
    }

    public  String strHandle(String str, Function<String,String> fun){
        return fun.apply(str);
    }

    /**
     * Predicate<T>
     */
    @Test
    public void PredicateTest(){

        List<String> list1= Arrays.asList("Predicate","Function","Supplier","Consumer");
        List<String> list=filterList(list1,(s)->s.length()>8);
        for (String s : list) {
            System.out.println(s);
        }
    }

    public List<String>  filterList(List<String> list, Predicate<String> predicate){
        List<String> strings=new ArrayList<>();
        for (String string : list) {
            if(predicate.test(string)){
                strings.add(string);
            }
        }
        return strings;

    }
发布了65 篇原创文章 · 获赞 74 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_40866897/article/details/90648791