【问题标题】:In java 8+ are only single argument method reference permitted in a stream在 java 8+ 中,流中只允许单个参数方法引用
【发布时间】:2018-12-31 09:39:31
【问题描述】:

说在 Java 8 的 Stream 中,您是否只能使用带有单个参数的方法引用(如果您不允许使用方法调用包装方法引用)?

我假设是因为在任何时候您都在处理单个项目的流中。

因此:

  • Something::new(必须引用单个 arg 构造函数)
  • this::doSomething(必须带一个 arg)
  • Something::doSomething (必须带一个 arg)

...在Stream 中使用时。这条规则总是正确的吗?

【问题讨论】:

    标签: java lambda java-8 functional-programming java-stream


    【解决方案1】:

    不,不是。一些Stream 方法采用具有多个参数的方法的功能接口。

    例如,Streamsorted(Stream<T> Comparator<? super T> comparator) 方法采用Comparator,其方法有两个参数。

    这是一个使用方法引用的示例 - String::compareTo - 具有两个参数的方法:

    System.out.println(Stream.of("a","d","c").sorted(String::compareTo).collect(Collectors.toList()));
    

    StreamOptional<T> max(Comparator<? super T> comparator) 方法是另一个类似的例子。

    【讨论】:

    • 但在这种情况下,方法引用被包装在方法调用 (toMap) 中。在我的问题中,我问的是任何未包装的情况。
    • 优秀。我认为您回答的第二部分已经回答了我的问题。
    【解决方案2】:

    方法引用有四种类型:

    • 对静态方法的方法引用,即

      Class::staticMethod --> (args) -> Class.staticMethod(args)

    • 对特定类型对象的实例方法的方法引用。即

      ObjectType::instanceMethod --> (obj, args) -> obj.instanceMethod(args)

    • 对现有对象的实例方法的方法引用,即

      obj::instanceMethod --> (args) -> obj.instanceMethod(args)

    • 对构造函数的方法引用,即

      ClassName::new --> (args) -> new ClassName(args)

    正如您在第二个示例中看到的那样,给定的方法可以接受两个参数并且仍然被转换为方法引用,这对于调用 sortedminmax 等的情况是正确的。的一条流。

    以上示例归功于Java 8 Method Reference: How to Use it

    【讨论】:

    • 只是添加一个点:ObjectType::instanceMethod 也可以是obj -> obj.instanceMethod(),其中obj 的类型是ObjectType
    【解决方案3】:

    只是添加到answer from Eran,您可能会找到一个更好理解的真实示例。

    假设我们有一个方法,它添加了 Long lInteger iintValue 以作为 String s 表示返回。这看起来像:

    String convertToStringAfterAddingValues(Long l, Integer i) {
        return String.valueOf(l.intValue() + i);
    }
    

    FunctionalInterface 的世界中,这可以表示为BiFunction 作为匿名类:

    BiFunction<Long, Integer, String> biFunctionAnonymous = new BiFunction<Long, Integer, String>() {
        @Override
        public String apply(Long l, Integer i) {
            return String.valueOf(l.intValue() + i);
        }
    };
    

    在 lambda 世界中可以表示为:

    BiFunction<Long, Integer, String> biFunctLambda = (l, i) -> String.valueOf(l.intValue() + i);
    

    同样可以使用方法引用与该方法所在的类的对象表示:

    BiFunction<Long, Integer, String> biFunctMethodReference = <YourClassInstance>::convertToStringAfterAddingValues;
    

    【讨论】:

    • 这很有用,但我认为它不能解决问题。
    • @AndyCribbens 这只是一个示例,说明如何使用方法引用在流中使用多个参数。无论如何,你的问题的确切答案是由 Eran 提供的。只是与您的问题Something::doSomething (must take a single arg) 和上面示例中的最后一行代码进行比较,您可以看到它是如何不依赖单个参数,而是同时依赖两个参数。
    猜你喜欢
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    相关资源
    最近更新 更多