【问题标题】:Definition of Functional Interface in Java 8 [duplicate]Java 8中功能接口的定义[重复]
【发布时间】:2016-04-25 15:06:25
【问题描述】:

Java 8 中函数式接口的定义说:

功能接口被定义为具有完全的任何接口 一个显式声明的抽象方法。 (资格是 必要的,因为接口可能有非抽象的默认方法。) 这就是为什么函数式接口过去被称为单一抽象的原因 方法 (SAM) 接口,这个术语仍然有时会出现。

那么我们怎么会有这个:

List<Double> temperature = 
   new ArrayList<Double>(Arrays.asList(new Double[] { 20.0, 22.0, 22.5 }));
temperature.sort((a, b) -> a > b ? -1 : 1);

由于List 中的sort 方法是:

default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

而 lambda 表达式说:

Lambda 表达式应该可以分配给功能接口

Comparator 接口有两个抽象方法compareequals,并带有@FunctionalInterface 注释。这不违反只有一个抽象方法的功能接口的定义吗?

【问题讨论】:

  • Java 中的每个类都继承自Object,并具有隐式方法Object::toStringObject::equalsObject::hashCode。因此Comparator&lt;T&gt; 是一个带有 SAM 的接口,它覆盖了隐式方法。
  • 你从哪里得到这个定义的?
  • 我在很多博客中阅读了我上面分享的定义。而且根据 stackoverflow 的指导方针,我不能分享到其他博客的链接..
  • 不要将您的知识建立在博客上。有enoughofficialmaterial学习。您可以使用 3rd 方教程和博客,但如果它们引起混淆,请使用官方来源进行验证。

标签: java java-8 functional-interface


【解决方案1】:

Comparator 接口确实有 2 个抽象方法。但是其中之一是equals,它覆盖了Object类中定义的equals方法,这个方法不算。

来自@FunctionalInterface

如果一个接口声明了一个覆盖java.lang.Object 的公共方法之一的抽象方法,那么也不会计入接口的抽象方法计数,因为该接口的任何实现都将具有来自java.lang.Object 或其他地方。

因此,这使得Comparator 接口成为函数式接口,其中函数式方法为compare(o1, o2)

lambda 表达式 (a, b) -&gt; a &gt; b ? -1 : 1 符合该约定:它声明了 2 个参数并返回一个 int

【讨论】:

  • 如果我们在这里,应该强调的是,与问题引用中声称的不同,这个定义不需要明确声明抽象方法。
  • 并且需要说明的是,这个 lambda 表达式虽然符合函数的 shape 并因此被编译器接受,但它违反了 contract 的Comparator 接口,并可能在运行时导致任意混乱......
  • 是的,在这种情况下Comparator.reverseOrder() 会是更好的选择。
猜你喜欢
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-24
  • 2016-08-21
相关资源
最近更新 更多