JDK8新特性 Lombda表达式复习

JDK8新特性 Lombda表达式复习

自定义函数式接口——@FunctionalInterface作用

jdk自带的一些常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KhdBWhB7-1626511804643)(https://xk857.com/typora/2021/05image-20210717102035113.png)]

说明

  1. 该注解只能标记在"有且仅有一个抽象方法"的接口上。
  2. JDK8接口中的静态方法和默认方法,都不算是抽象方法。
  3. 接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
  4. 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。
  5. 为了规范,建议给所有需要使用函数式编程的接口都加上注解。

解析

1、只有一个抽象方法的情况

@FunctionalInterface
public interface MyInterface {
    
    int test(int i);
}

2、有多个方法,但只有一个抽象方法,其他方法有默认实现

@FunctionalInterface
public interface MyInterface {

    int test(int i);

    default int add(int a, int b) {
        return a + b;
    }

    default void sum(int a, int b) {
        System.out.println("sum:" + a + b);
    }
}

使用

为了方便理解,我们使用一下,看看效果

public static void main(String[] args) {
    // 使用lombda实现test方法
    MyInterface myInterface = i -> i*2;
    
    // 调用刚刚实现的方法
    System.out.println(myInterface.test(22));
    
    // 调用默认重写的方法
    System.out.println(myInterface.add(10,20));
    myInterface.sum(100,20);
}

结果

44
30
sum:10020

函数接口1—将接口用于方法参数

需求:新建一个类,传入余额。类中定义一个方法,方法参数为接口,自定义余额格式化信息。

自定义接口

@FunctionalInterface
public interface SecondInterface {

    /**
     * 格式化金额
     */
    String format(int i);

}

格式化金额类

class MyMoney{
    private final int money;

    public MyMoney(int money) {
        this.money = money;
    }

    public void printMoney(SecondInterface secondInterface){
        System.out.println("我的存款:"+secondInterface.format(this.money));
    }
}

使用:

public static void main(String[] args) {
    MyMoney myMoney = new MyMoney(999999);
    myMoney.printMoney(i -> new DecimalFormat("#,###").format(i));
}

结论:我们使用lombda不需要关心接口名称是什么,只要关心传入的参数是什么,想让参数变成什么类型。

函数接口2—jdk自带函数接口

接口输入参数返回类型使用说明
PredicateTboolean断言
ConsumerT/消费一个数据
Function<T,R>TR输入T输出R的函数
Supplier/T提供一个数据
UnaryOperatorTT一元函数(输入输出类型相同)
BiFunction<T,U,R>(T,U)R两个输入的函数
BinaryOperator(T,T)T二元函数(输入输出类型相同)

使用

public static void main(String[] args) {
    // 断言
    Predicate<Integer> predicate = i -> i > 0;
    System.out.println(predicate.test(-1));

    // 消费
    Consumer<String> consumer = s -> System.out.println(s);
    consumer.accept("张三");

    // 输入T输出R
    Function<Integer, String> function = i -> i >= 0 ? "正数" : "负数";
    function.apply(7);

    // 提供一个数据
    Supplier<String> stringSupplier = () -> "测试";
    System.out.println(stringSupplier.get());

    // 一元函数
    UnaryOperator<String> unaryOperator = s -> "处理后" + s;
    System.out.println(unaryOperator.apply("Test"));

    // 两个输入的函数
    BiFunction<String,Boolean,Integer> biFunction = (s, b) -> {
        // 如果b为true,返回0;如果s为test返回1,否则返回-1
        if (b){
            return 0;
        }
        if ("test".equals(s)){
            return 1;
        }
        return -1;
    };
    System.out.println(biFunction.apply("test", false));

    // 二元函数
    BinaryOperator<String> binaryOperator = (s, s2) -> s+s2;
    System.out.println(binaryOperator.apply("雷军", "666"));
}

结果

false
张三
测试
处理后Test
1
雷军666

方法引用 ::

方法引用符 ::

先来简单体验一下

public static void main(String[] args) {
    Consumer<String> consumer1 = s -> System.out.println(s);
    consumer1.accept("张三");

    Consumer<String> consumer2 = System.out::println;
    consumer2.accept("张三");
}

静态方法的方法引用

类名::方法名

新建 dog

public class Dog {

    private String name;

    public Dog(String name) {
        this.name = name;
    }
    public static void bark(Dog dog) {
        System.out.println(dog.name + "叫了");
    }
}

引用静态方法 “bark

public static void main(String[] args) {
    Consumer<Dog> consumer = Dog::bark;
    consumer.accept(new Dog("哮天犬"));
}

控制台输出:哮天犬叫了

非静态方法使用对象实例引用

改变 Dog 类中的 bark 方法

public class Dog {

    private String name;

    public Dog(String name) {
        this.name = name;
    }
    public void bark(Dog dog) {
        System.out.println(dog.name + "叫了");
    }
}

使用:

public static void main(String[] args) {
    Dog dog = new Dog("张三");
    Consumer<Dog> consumer = dog::bark;
    consumer.accept(dog);
}

控制台输出:张三叫了

无参构造方法的引用

public class Dog {

    private String name;
    
    // 无参构造
    public Dog() {}

    public void bark(Dog dog) {
        System.out.println(dog.name + "叫了");
    }
}

使用

public static void main(String[] args) {
    Supplier<Dog> supplier = Dog::new;
    Dog dog = supplier.get();
}

有参构造方法的引用

public class Dog {

    private String name;


    // 有参构造
    public Dog(String name) {
        this.name = name;
    }

    public void bark(Dog dog) {
        System.out.println(dog.name + "叫了");
    }
}

使用

public static void main(String[] args) {
    // 接收string,输出Dog,jdk会自动找到有参构造
    Function<String,Dog> function = Dog::new;
    Dog dog = function.apply("张三");
    dog.bark(dog);
}

控制台输出:张三叫了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV大魔王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值