【问题标题】:Understanding Java 8 Lambda Expressions [closed]了解 Java 8 Lambda 表达式 [关闭]
【发布时间】:2020-07-17 11:37:45
【问题描述】:

我正在阅读有关 Java 8 的 this article 并有以下问题/cmets 我希望得到一些反馈/回复。

1) 下面的代码需要@FunctionalInterface 声明吗?或者是否可以在没有它的情况下执行相同的代码并且它是出于文档目的?从文章中看是否有必要还不清楚。

@FunctionalInterface
private interface DTOSender {
   void send(String accountId, DTO dto);
}

void sendDTO(BisnessModel object, DTOSender dtoSender) {
   //some logic for sending...
   ...
   dtoSender.send(id, dto);
   ...
}

2) 一般来说,一个函数可以作为参数传递给 Java 8 中的另一个函数吗?我的理解是只有数据类型可以作为参数传递给函数,所以我认为这是不可能的,因为函数不是数据类型。

3) 我是否需要做一些特别的事情来完成上面的#2,或者我可以只写我对这两种方法的定义,然后将一种方法作为参数传递给另一种方法吗?

4) 对象可以作为参数传递给 Java 8 中的另一个函数吗?我是否需要做一些特别的事情来完成这项工作,或者我可以只编写对象和方法的定义,然后将对象作为参数传递给方法?

【问题讨论】:

  • (1) 就像在大多数情况下documentation 持有答案:“但是,编译器会将满足功能接口定义的任何接口视为功能接口无论是否接口声明中存在一个 FunctionalInterface 注释。"
  • 谢谢——我也是这么想的,但我一定是错过了。您能否对其他问题发表评论?
  • 抱歉,我现在很忙。顺便说一句,你应该ask one question per post
  • 感谢您的帮助 - 我觉得它们是相关的概念,并且有点小且有条件,所以我想我只是将它们结合起来
  • 我会声明 Java 中没有函数。只有方法——无论是静态的还是非静态的——,还有接口Function

标签: java lambda java-8 functional-programming higher-order-functions


【解决方案1】:

注释@FunctionalInterface 不是文档所述的强制要求。

为了将函数传递给您的方法,必须有一个匹配的函数接口。

interface ListFilter<T> {
    boolean test(T item);
}

public static <T extends Comparable<T>> List<T> filter(List<T> list, ListFilter<T> filter) {
    List<T> filteredList = new ArrayList<>();
    for (T t : list) {
        if (filter.test(t)) {
            filteredList.add(t);
        }
    }
    return filteredList;
}

public static boolean isNumberGreaterThan2(Integer integer){
    return integer > 2;
}

public static void main(String[] args) {
    List<Integer> list = List.of(1, 2, 3, 4);
    filter(list, new ListFilter<Integer>() {
        @Override
        public boolean test(Integer item) {
            return item > 2;
        }
    });
    // or
    filter(list, item -> item > 2);
    // or
    filter(list, Main::isNumberGreaterThan2);
}

【讨论】:

  • 我会说它是由文件暗示的,但它并没有完全说明。例如,“覆盖”需要@,因为它被使用时;但我猜“FunctionalInterface”没有必要
  • 那么如果函数可以在不使用 lambda 的情况下作为参数传递给其他函数,那么 lambda 表达式的好处仅仅是为了让读者更清楚吗?
  • @user3216798 是的,这只是一个速记
  • sn-p 如何与您所说的相关联。你为什么要重新定义println
  • @Andronicus 我试图在示例中说明要将现有函数传递给另一个函数,您要传递的函数必须与指定为参数的函数接口匹配。
【解决方案2】:
  1. @Functional Interface 只是一个提示,这样你就不会在你的界面中加入更多的方法。

  2. 可以。 Stream 上的许多方法都以函数为参数:Stream.of(1, 2, 3).forEach(System.out::println)

  3. Lambda 是一个函数实例Function&lt;Integer, Integer&gt; f = a -&gt; a + 1。编辑:您可以使用方法引用按名称传递函数(参见 2.,println 是常规方法)。

  4. 我没有完全理解这个问题。如果该方法使用任何非原始参数,则它需要一个对象(Java 中除了原始对象之外的所有内容都是一个对象)。

【讨论】:

  • @user3216798 有很多好处。可读性是最明显的因素之一
  • @user3216798 我已经在第二点做了;> System.out::println 按名称引用 println 方法。这是PrintStream上定义的常规方法。
  • 对否决票有何评论?
  • @user3216798 是的,通过method references,它基本上是简单调用单个方法的 lambda 表达式的简写。例如,此答案中的 forEach(System.out::println) 示例等效于 forEach(e -&gt; System.out.println(e)) 并且它正在调用 System.out 实例的 PrintStream#println 方法。
  • @user3216798 虽然技术上你并没有传递一个方法。 lambda 表达式和方法引用都创建函数式接口的实例,它是您传递的函数式接口的实例。
猜你喜欢
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多