标签: method-reference

在Java 8中,"特定类型的任意对象"是什么意思?

在Java 8中有"方法参考"功能.其中一种是"引用特定类型的任意对象的实例方法"

http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html#type

有人可以解释"特定类型的任意对象"在这种情况下的含义吗?

java java-8 method-reference

16
推荐指数
4
解决办法
8943
查看次数

方法参考的组成

这与这个问题有关:如何进行功能组合?

我注意到方法引用可以分配给声明为的变量Function,因此我假设它应该具有andThencompose函数,因此我希望我们可以直接组合它们.但很显然,我们需要把它们分配给声明为可变的Function第一(或类型转换调用之前)之前,我们可以称之为andThencompose他们.

我怀疑我可能会对这应该如何运作有一些误解.

所以我的问题:

  1. 在调用andThen方法之前,为什么我们需要先键入或将其分配给变量?
  2. 以这种方式需要完成的方法引用的类型究竟是什么?

示例代码如下.

public class MyMethods{
    public static Integer triple(Integer a){return 3*a;}
    public static Integer quadruple(Integer a){return 4*a;}

    public int operate(int num, Function<Integer, Integer> f){
        return f.apply(num);
    }

    public static void main(String[] args){
        MyMethods methods = new MyMethods();
        int three = methods.operate(1, MyMethods::triple); // This is fine
        // Error below
        // int twelve = methods.operate(1, (MyMethods::triple).andThen(MyMethods::quadruple));
        // But this one is …
Run Code Online (Sandbox Code Playgroud)

java eclipse function-composition java-8 method-reference

16
推荐指数
2
解决办法
4009
查看次数

Java 8链式方法参考?

假设有一个典型的Java Bean:

class MyBean {
    void setA(String id) {
    }

    void setB(String id) { 
    }

    List<String> getList() {
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在BiConsumer的帮助下创建一种更抽象的方式来调用setter:

Map<SomeEnum, BiConsumer<MyBean, String>> map = ...
map.put(SomeEnum.A, MyBean::setA);
map.put(SomeEnum.B, MyBean::setB);
map.put(SomeEnum.List, (myBean, id) -> myBean.getList().add(id));
Run Code Online (Sandbox Code Playgroud)

有没有一种方法,以取代拉姆达(myBean, id) -> myBean.getList().add(id)与链接的方法引用,类似(myBean.getList())::add或者myBean::getList::add还是其他什么东西?

java lambda java-8 method-reference

16
推荐指数
1
解决办法
7908
查看次数

为什么将此Java方法调用视为模棱两可?

我遇到了奇怪的错误消息,我认为这可能是不正确的。考虑以下代码:

public class Overloaded {
    public interface Supplier {
        int get();
    }

    public interface Processor {
        String process(String s);
    }

    public static void load(Supplier s) {}
    public static void load(Processor p) {}

    public static int genuinelyAmbiguous() { return 4; }
    public static String genuinelyAmbiguous(String s) { return "string"; }

    public static int notAmbiguous() { return 4; }
    public static String notAmbiguous(int x, int y) { return "string"; }

    public static int strangelyAmbiguous() { return 4; }
    public static String strangelyAmbiguous(int …
Run Code Online (Sandbox Code Playgroud)

java overloading arity functional-interface method-reference

15
推荐指数
1
解决办法
377
查看次数

Objects :: nonNull和x - > x!= null之间有什么区别吗?

考虑以下课程:

import java.util.Objects;
import java.util.function.Predicate;

public class LambdaVsMethodRef {
    public static void main(String[] args) {
        Predicate<Object> a = Objects::nonNull;
        Predicate<Object> b = x -> x != null;
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个谓词是从方法引用创建的,另一个是lambda表达式.这些谓词具有相同的行为(nonNull正文是正确的return obj != null;).lambda缩短了两个字符(可能允许流管道适合一行).

除了代码风格,之间有什么区别?换句话说,我应该更喜欢一个吗?Objects::nonNullx -> x != null

拉姆达-dev的和λ-库-规格- {观察员,专家}邮件列表邮件提isNull,nonNull以及isNotNull(初名)并没有解决这个问题.(我很惊讶没有人质疑添加Objects方法,因为它们可以用lambda轻松替换,但另一方面,也是如此Integer::sum.)

我也查看了字节码javap.唯一的区别是传递给lambda metafactory bootstrap方法的方法句柄:

  BootstrapMethods:
0: #16 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
  Method arguments:
    #17 (Ljava/lang/Object;)Z
    #18 invokestatic java/util/Objects.nonNull:(Ljava/lang/Object;)Z
    #17 (Ljava/lang/Object;)Z
1: #16 invokestatic …
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 method-reference

14
推荐指数
1
解决办法
8749
查看次数

Java 8方法参考非静态方法

为什么这不起作用?我得到编译错误"无法对非静态方法打印静态引用..."

public class Chapter3 {
    public void print(String s) {
        System.out.println(s);
    }
    public static void main(String[] args) {
        Arrays.asList("a", "b", "c").forEach(Chapter3::print);
    }
}
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference

14
推荐指数
4
解决办法
1万
查看次数

在Java8中引用具有不同参数的方法

我想知道方法引用和功能接口的所有这些东西如何在较低级别上工作.最简单的例子是我们有一些List

List<String> list = new ArrayList<>();
list.add("b");
list.add("a");
list.add("c"):
Run Code Online (Sandbox Code Playgroud)

现在我们想用Collections类对它进行排序,所以我们可以调用:

Collections.sort(list, String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)

但是,如果我们定义自定义比较器,它可能是这样的:

Comparator<String> customComp = new MyCustomOrderComparator<>();
Collections.sort(list, customComp::compare);
Run Code Online (Sandbox Code Playgroud)

问题是Collections.sort有两个参数:List和Comparator.由于Comparator是功能接口,因此可以使用具有相同签名(参数和返回类型)的lambda表达式或方法引用替换它.那么它是如何工作的,我们也可以传递compareTo只引用一个参数并且这些方法的签名不匹配?如何在Java8中翻译方法引用?

java java-8 method-reference

14
推荐指数
1
解决办法
7121
查看次数

为什么这个Java 8方法参考编译?

我正在深入探讨 Java 8 Lambda和方法参考等功能.玩了一下让我看到以下示例:

public class ConsumerTest {

  private static final String[] NAMES = {"Tony", "Bruce", "Steve", "Thor"};

   public static void main(String[] args) {
      Arrays.asList(NAMES).forEach(Objects::requireNonNull);
   }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

为什么main方法中的行会编译?

如果我理解正确的话,引用的方法的签名必须对应于功能接口的SAM签名.在这种情况下,消费者需要以下签名:

void accept(T t);
Run Code Online (Sandbox Code Playgroud)

但是,该requireNonNull方法返回T而不是void:

public static <T> T requireNonNull(T obj)
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference

14
推荐指数
1
解决办法
7690
查看次数

SONAR:用方法引用替换此lambda

声纳告诉我"用方法参考替换这个lambda"

public class MyClass {

    private List<SomeValue> createSomeValues(List<Anything> anyList) {
        return anyList //
               .stream() //
               .map(anything -> createSomeValue(anything)) //
               .collect(Collectors.toList());
   }

    private SomeValue createSomeValue(Anything anything) {
        StatusId statusId = statusId.fromId(anything.getStatus().getStatusId());
        return new SomeValue(anything.getExternId(), statusId);
    }

}
Run Code Online (Sandbox Code Playgroud)

这可能吗?我尝试了几件事,比如

.map(MyClass::createSomeValue) //
Run Code Online (Sandbox Code Playgroud)

但我需要将方法更改为静态.而且我不是静态方法的忠实粉丝.

SonarQube的解释是:

方法/构造函数引用比使用lambdas更紧凑和可读,因此是首选.

java lambda java-8 sonarqube method-reference

14
推荐指数
1
解决办法
1万
查看次数

对数组clone()的方法引用会导致NoClassDefFoundError:Array

当我运行此代码时

List<int[]> list = Arrays.asList(new int[]{1, 2, 3}, new int[]{4, 5});
int[][] arr = list.stream().map(j -> j.clone()).toArray(int[][]::new);
System.out.println(Arrays.deepToString(arr));
Run Code Online (Sandbox Code Playgroud)

它按预期工作,我得到输出

[[1, 2, 3], [4, 5]]
Run Code Online (Sandbox Code Playgroud)

但是,如果我用方法引用替换lambda clone()

int[][] arr = list.stream().map(int[]::clone).toArray(int[][]::new);
Run Code Online (Sandbox Code Playgroud)

我得到一个运行时异常:

Exception in thread "main" java.lang.NoClassDefFoundError: Array
    at Main.lambda$MR$main$clone$8ed4b78b$1(Main.java:14)
    at Main$$Lambda$1/1160460865.apply(Unknown Source)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:576)
    at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:255)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438)
    at Main.main(Main.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassNotFoundException: Array
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method) …
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference

13
推荐指数
1
解决办法
436
查看次数