前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jdk8函数接口

jdk8函数接口

作者头像
GreizLiao
发布2020-03-03 10:40:27
6660
发布2020-03-03 10:40:27
举报
文章被收录于专栏:足球是圆的

java8 新特性推出的 Lambda 表达式,即函数式编程,相信很多开发胸弟都会使用了,但是什么是函数式编程呢?别问我,我也不知道标准的定义。其核心思想是:使用不可变值和函数,函数对一个值进行处理,映射成另一个值

函数接口

java8之前接口类只有方法的定义,没有实现的,Java8对接口提供默认方法的新特性。一个接口类可以定义n个抽象方法,但如果有 @FunctionalInterface 注解修饰就不一样了,该注释会强制编译检查一个接口是否符合函数接口的标准。如果该注释添加给一个枚举类型、类或另一个注释,或者接口包含不止一个抽象方法,编译就会报错。@FunctionalInterface 注解修饰的接口就是被定义成函数接口。

常用的函数接口

平时开发中常用的函数接口有无返回值的Consumer,返回值为Boolean的Predicate,把入参T映射成R返回值的Function 和返回实例对象的Supplier。接下来我们一起分析这四个函数接口类的源码以及简单的使用,先创建一个后面需要用到的实体类 Griez。

代码语言:javascript
复制
public class Griez implements Serializable {
    private int age;
    private String name;
    public Griez(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public Griez setAge(int age) {
        this.age = age;
        return this;
    }

    public String getName() {
        return name;
    }

    public Griez setName(String name) {
        this.name = name;
        return this;
    }
}

定义一个法国球星格子(我最喜欢的球员)类,为了简单这里只有名字和年龄,他的能力值和薪资就不展示出来了,怕吓到大家。

Consumer

代码语言:javascript
复制
@FunctionalInterface
public interface Consumer<T> {
        // 执行时需要调用传入的实现
    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

Consumer函数接口有两个方法,抽象方法accept需要调用者自己实现;andThen默认方法封装了两个Consumer执行顺序的Consumer实例,先执行本实例的accept,再执行参数after的accept方法。

代码语言:javascript
复制
    public static void main(String[] args) {
        Consumer<Griez> consumer = griez -> System.out.println(griez.getName() + griez.age);
        Consumer<Griez> afterConsumer = griez -> System.out.println(griez.getAge());
        Consumer<Griez> then = consumer.andThen(afterConsumer);
        then.accept(new Griez(29, "wolf"));
    }

第1,2行创建Consumer实例,并实现了accept方法。记得刚毕业出来面试有个面试官问我接口能不能创建实例,我给他的回答是:“你说呢?”。

Predicate

代码语言:javascript
复制
@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);
        // 两个条件必须满足
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    // 传说中的 逻辑非 判断
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    // 逻辑或判断
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    // 对象判断?
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

test 方法需要自定义逻辑,返回一个boolean值,该函数接口是做判断用途的。and 方法是两个Predicate 逻辑与判断;negate 方法是逻辑非判断;or 方法是两个 Predicate 逻辑或判断;isEqual 方法是判断targetRef是否与本实例相同。

代码语言:javascript
复制
public static void main(String[] args) {
    Predicate<Griez> predicate= griez -> griez.getAge() > 18;
    System.out.println("Griez已经成年了 : " + predicate.test(new Griez(29, "griez")));
}

test返回Boolean值。

Function

代码语言:javascript
复制
@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

apply 方法接收一个T参数,然后一个R,该方法是类型映射作用。compose 方法是组装了两个Function执行顺序行为Function对象,先执行参数的Function在执行本实例Function。andThen 跟 compose执行顺序相反。identity 方法是返回参数本身。

代码语言:javascript
复制
public static void main(String[] args) {
    Function function = o -> new Griez(20, "Female");
    System.out.println(function.apply(new Griez(29, "griez").getName()));
}

一个大老爷进去变成一个年轻小姐姐出来,变态的程序员。

Supplier

代码语言:javascript
复制
@FunctionalInterface
public interface Supplier<T> {
    T get();
}

该函数接口看上去就比较寒颤了,只有一个方法。get 方法作用如名字一个,伸手党来的,获取一个实例。

代码语言:javascript
复制
public static void main(String[] args) {
    Supplier<Griez> supplier = () -> new Griez(29, "griez");
    System.out.println(supplier.get());
}

获取一个Griez对象。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数接口
  • 常用的函数接口
    • Consumer
      • Predicate
        • Function
          • Supplier
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档