Java 基础(Lambda表达式 和 函数式 Functional 接口)

Lambda表达式

函数式 Functional 接口

  1. 只包含一个抽象方法的接口,称为函数式接口。
  2. 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
  3. 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
  4. 在 java.util.function 包下定义了Java 8的丰富的函数式接口
  5. Java 从诞生日起就是一直倡导 “一切皆对象”,在Java里面面向对象(OOP)编程是一切。但是随着python、scala等语言的兴起和新技术的挑战,Java不得不做出调整以便支持更加广泛的技术要求,也即 java 不但可以支持OOP还可以支持OOF(面向函数编程)
  6. 在函数式编程语言当中,函数被当做一等公民对待。在将函数作为一等公民的编程语言中,Lambda表达式的类型是函数。但是在Java8中,有所不同。在Java8中,Lambda表达式是对象,而不是函数,它们必须依附于一类特别的对象类型——函数式接口。
  7. 简单的说,在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
  8. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。

Java 内置四大核心函数式接口

其他接口

LambdaTest.java

package com.klvchen.java1;

import org.junit.Test;

import java.util.Comparator;

public class LambdaTest {

    @Test
    public void test1(){

        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我爱北京天安门");
            }
        };

        r1.run();

        System.out.println("**********************************");

        Runnable r2 = () -> System.out.println("我爱北京故宫");

        r2.run();
    }

    @Test
    public void test2(){

        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };

        int compare1 = com1.compare(12, 21);
        System.out.println(compare1);

        System.out.println("***************************************");

        Comparator<Integer> com2 = (o1, o2) -> Integer.compare(o1,o2);

        int compare2 = com2.compare(32, 21);
        System.out.println(compare2);

        System.out.println("***************************************");
        //方法引用
        Comparator<Integer> com3 = Integer :: compare;

        int compare3 = com3.compare(32, 21);
        System.out.println(compare3);

    }
}

LambdaTest1.java

package com.klvchen.java1;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Consumer;

/*
   Lambda表达式的使用
   1.举例: (o1,o2) -> Integer.compare(o1,o2);

   2.格式:
         ->左边: Lambda形参列表的参数类型可以省略(类型推断);如果Lambda形参列表只有一个参数,其一对()也可以省略
         ->右边: Lambda体应该使用一对{}包裹;如果Lambda体只有一条执行语句(可能是return语句),可以省略这一对{}和return关键字

   3.Lambda 表达式的使用:(分为6种情况)

   4.Lambda 表达式的本质:作为接口的实例

   5.如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口

   6.所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。

 */
public class LambdaTest1 {
    // 语法格式一:无参,无返回值
    @Test
    public void test1(){
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("我爱北京天安门");
            }
        };

        r1.run();

        System.out.println("*****************************");

        Runnable r2 = () -> System.out.println("我爱北京故宫");

        r2.run();
    }

    //语法格式二:Lambda需要一个参数,但是没有返回值。
    @Test
    public void test2(){
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };

        con.accept("谎言和誓言的区别是什么?");

        System.out.println("*****************************");

        Consumer<String> con1 = (String s) -> {
            System.out.println(s);
        };

        con1.accept("一个是听得人当真了,一个是说的人当真了");
    }

    //语法格式三:数据类型可以省略,因为可由编译器推断得出,称为"类型推断"
    @Test
    public void test3(){
        Consumer<String> con1 = (String s) -> {
          System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");

        System.out.println("*****************************");

        Consumer<String> con2 = (s) ->{
            System.out.println(s);
        };

        con2.accept("一个是听得人当真了,一个是说的人当真了");
    }

    @Test
    public void test4(){
        ArrayList<String> list = new ArrayList<>();//类型推断

        int[] arr = {1, 2, 3};//类型推断
    }

    //语法格式四: Lambda若只需要一个参数时,参数的小括号可以省略
    public void test5(){
        Consumer<String> con1 = (s) -> {
            System.out.println(s);
        };
        con1.accept("一个是听得人当真了,一个是说的人当真了");

        System.out.println("*****************************");

        Consumer<String> con2 = s -> {
            System.out.println(s);
        };

        con2.accept("一个是听得人当真了,一个是说的人当真了");
    }

    //语法格式五:Lambda需要两个或以上的参数,多条执行语句,并且可以有返回值
    @Test
    public void test6(){
        Comparator<Integer> com1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return o1.compareTo(o2);
            }
        };

        System.out.println(com1.compare(12,21));

        System.out.println("*****************************");
        Comparator<Integer> com2 = (o1,o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };

        System.out.println(com2.compare(12,6));
    }

    //语法格式六:当Lambda体只有一条语句时,return 与大括号若有,都可以省略
    @Test
    public void test7(){
        Comparator<Integer> com1 = (o1, o2) -> {
            return o1.compareTo(o2);
        };

        System.out.println(com1.compare(12, 6));

        System.out.println("******************************************************");

        Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2);

        System.out.println(com2.compare(12, 21));

    }

    @Test
    public void test8(){
        Consumer<String> con1 = s -> {
            System.out.println(s);
        };

        con1.accept("一个是听得人当真了,一个是说的人当真了");

        System.out.println("******************************************************");

        Consumer<String> con2 = s -> System.out.println(s);

        con2.accept("一个是听得人当真了,一个是说的人当真了");
    }



}

LambdaTest2.java

package com.klvchen.java1;

/*
  java内置的4大核心函最式接口
  消费型接口  Consumer<T>    void accept(T t)
  供给型接口  Supplier<T>    T get()
  函数型接口  Function<T,R>  R apply(T t)
  断定型接口  Predicate<T>   booLean test(T t)
 */

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class LambdaTest2 {

    @Test
    public  void test1(){
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("学习太累了,去天上人间买了瓶矿泉水,价格为: " + aDouble);
            }
        });

        System.out.println("**************************************************");

        happyTime(400, money -> System.out.println("学习太累了,去天上人间买了瓶矿泉水,价格为: " + money));

    }

    public void happyTime(double money, Consumer<Double> con) {
        con.accept(money);
    }


    @Test
    public void test2(){
        List<String> list = Arrays.asList("北京","南京","天津","东京","西京","普京");

        List<String> filterStrs = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });

        System.out.println(filterStrs);

        List<String> filterStrs1 = filterString(list, s -> s.contains("京"));

        System.out.println(filterStrs1);
    }

    //据给定的规剩,过滤集合中的字符串。此规则由Predicate的方法决定
    public List<String> filterString(List<String> list, Predicate<String> pre){

        ArrayList<String> filterList = new ArrayList<>();

        for (String s : list) {
            if (pre.test(s)){
                filterList.add(s);
            }
        }

        return filterList;
    }
}

posted @ 2021-11-28 10:19  klvchen  阅读(126)  评论(0编辑  收藏  举报