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

Lambda01-Functional 函数式接口

作者头像
潇洒
发布2023-10-20 12:36:23
1350
发布2023-10-20 12:36:23
举报
文章被收录于专栏:石头岛

Functional 为 lambda 方法提供一个接口

函数式接口

Functional 的定义其实很简单:任何接口,如果只包含 唯一一个抽象方法,那么它就是一个 Functional Interface , 函数式接口?这注解名字好。 为了让编译器帮助我们确保一个接口满足 Functional Interface 的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解。

先学习函数式接,才能理解学习 Lambda 表达式。

有什么用

白话:用来为函数式编程提供接口。 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。 函数式接口可以被隐式转换为 lambda 表达式。

简单示例

写一个最简单的例子做为入门参考,看不懂不要紧,这个只是一个例子。

声明一个无参的接口

声明一个无参函数式接口,为 lambda 提供一个接口。 在接口上添加@Functional那么这个接口就是一个函数式接口

代码语言:javascript
复制
@FunctionalInterface
public interfaceMyFunctional {
    public abstract void run ();
}

实现接口

自己实现一个Functional接口,只需要 ()-> System.out.println("test") 进行实现。()->System.out.println("test") 就是一个lambda实现。 这里主要关注Functional接口,不需要关注lambda

代码语言:javascript
复制
public class Test {
  public static void main(String[] args) {
    //实现 lambda
    MyFunctional myFunctional = () -> System.out.println("test");
    //调用 Functional 接口来执行 lambda 实现
    System.out.println(myFunctional.run());
  }
}

使用规则

首先它是一个接口。然后这个接口里面只能有一个抽象方法。 这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。

规则

  1. 函数式接口里允许定义默认方法,因为默认方法不是抽象方法,其有一个默认实现,所以是符合函数式接口的定义的
  2. 函数式接口里允许定义静态方法,因为静态方法不能是抽象方法,是一个已经实现了的方法,所以是符合函数式接口的定义的
  3. 函数式接口里允许定义Java.lang.Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了Object类,包含了来自java.lang.Object里对这些抽象方法的实现;
  4. 函数式接口里允许子接口继承多个父接口,但每个父接口中都只能存在一个抽象方,且必须的相同的抽象方法。

jdk 中的 lambda 实现示例

使用 Arrays 对数据进行排序。 Arrays 的 sort 方法,可以使用 lambda 的方法,这个方法是怎么实现的呢。 老套路:

  1. 定义 Functional 接口
  2. Functional 做为形参
  3. 有一个地方实现了这个Functional接口
  4. 调用
代码语言:javascript
复制
// 使用 lambda expression 排序 players
Comparator<String> sortByName = (s1, s2) -> (s1.compareTo(s2));
Arrays.sort(players, sortByName);

//等价形式
Arrays.sort(players, (s1, s2)-> (s1.compareTo(s2)));

看看 sort 的具体实现,sort 是对 Comparator 接口的具体实现。

代码语言:javascript
复制
public static <T> void sort(T[] a, Comparator<? super T> c) {
    if (c == null) {
        sort(a);
    } else {
        if (LegacyMergeSort.userRequested)
    legacyMergeSort(a, c);
        else
        TimSort.sort(a, 0, a.length, c, null, 0, 0);
    }
}

Comparator 接口

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

默认方法 和 静态方法

默认方法是可以直接被 类名.方法名使用的。 lambda 的默认实现方法,可以直接写在接口当中,然后具体使用的时候引用即可。 封装的时候也可以直接引用。

代码语言:javascript
复制
import java.util.Objects;
import java.util.function.Predicate;

@FunctionalInterface
public interface MyFunctional<T> {
    //只允许存在一个 public abstract 方法
     boolean test(T t);
    // 这个方法就是对上面  boolean test(T t);  的一个默认实现
    static <T> boolean getBoolean (T b) {
        System.out.println(b.toString());
        return true;
    }
    //由于使用了范形,入参就变得灵活
    default String testPrintString (String message) {
        System.out.println(message);        return message;
    }
    //使用范形方法
     default <T> boolean testPrint (T message) {
        System.out.println(message);        return true;
    }
        //允许存在默认方法
    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) {
       System.out.println("使用静态方法");
       return (null == targetRef)? Objects::isNull: object -> targetRef.equals(object);
    }
}
代码语言:javascript
复制
public static void testStaticMethod() {
  //直接使用默认实现
  static <T > boolean getBoolean (T b)
  MyFunctional myFunctional = MyFunctional::getBoolean;
  myFunctional.test(new Date());
  myFunctional.testPrintString("test....");
  //使用具体类型,默认方法
  myFunctional.testPrint(new Date());
  //使用范形默认方法
  // 直接传入默认实现即可
  testDefault(MyFunctional::getBoolean);
  //使用静态方法
  MyFunctional.isEqual(new Date());
}

//封装 lambda 表达式
public static String testDefault(MyFunctional myFunctional) {
  return myFunctional.testPrintString("just test lambda");
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数式接口
  • 有什么用
  • 简单示例
    • 声明一个无参的接口
      • 实现接口
      • 使用规则
        • jdk 中的 lambda 实现示例
          • 默认方法 和 静态方法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档