相关疑难解决方法(0)

Lambda表达式和方法重载疑问

好的,所以方法重载是一个糟糕的事情.既然已经解决了这个问题,我们假设我实际上想要重载这样的方法:

static void run(Consumer<Integer> consumer) {
    System.out.println("consumer");
}

static void run(Function<Integer, Integer> function) {
    System.out.println("function");
}
Run Code Online (Sandbox Code Playgroud)

在Java 7中,我可以使用非模糊的匿名类作为参数轻松地调用它们:

run(new Consumer<Integer>() {
    public void accept(Integer integer) {}
});

run(new Function<Integer, Integer>() {
    public Integer apply(Integer o) { return 1; }
});
Run Code Online (Sandbox Code Playgroud)

现在在Java 8中,我当然想用lambda表达式调用这些方法,我可以!

// Consumer
run((Integer i) -> {});

// Function
run((Integer i) -> 1);
Run Code Online (Sandbox Code Playgroud)

既然编译器应该能够推断出来Integer,为什么我不离开Integer呢?

// Consumer
run(i -> {});

// Function
run(i -> 1);
Run Code Online (Sandbox Code Playgroud)

但这不编译.编译器(javac,jdk1.8.0_05)不喜欢这样:

Test.java:63: error: reference to run is …
Run Code Online (Sandbox Code Playgroud)

java lambda overloading jls java-8

48
推荐指数
1
解决办法
8369
查看次数

Java8:lambdas和重载方法的歧义

我正在玩java8 lambdas,我遇到了编译器错误,我没想到.

假设我有一个函数interface A,一个abstract class B和一个class C重载方法,它们可以采用A或B作为参数:

public interface A { 
  void invoke(String arg); 
}

public abstract class B { 
  public abstract void invoke(String arg); 
}

public class C {
  public void apply(A x) { }    
  public B apply(B x) { return x; }
}
Run Code Online (Sandbox Code Playgroud)

然后我可以传入一个lambda c.apply,它正确地解决了c.apply(A).

C c = new C();
c.apply(x -> System.out.println(x));
Run Code Online (Sandbox Code Playgroud)

但是当我更改B作为泛型版本的参数的重载时,编译器报告两个重载是不明确的.

public class C {
  public void apply(A x) { …
Run Code Online (Sandbox Code Playgroud)

java generics lambda java-8

38
推荐指数
2
解决办法
7963
查看次数

用于功能接口的Java 8 lambda模糊方法 - 目标类型

我有以下代码:

public class LambdaTest1 {

    public static void method1(Predicate<Integer> predicate){
        System.out.println("Inside Predicate");
    }

    public static void method1(Function<Integer,String> function){
        System.out.println("Inside Function");
    }

    public static void main(String[] args) {        
        method1((i) -> "Test"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

这给我一个错误信息

"方法method1(谓词)对于LambdaTest1类型是不明确的".

我可以看到,对于Function和Consumer功能接口,输入参数是Integer.但对于Function,返回类型是String.

因为我的lambda调用具有返回值"Text" - 这应该调用我的Function函数接口而不是抛出此错误.

任何人都可以解释这种行为背后的原因吗?

另一个例子:

public class LambdaTest1 {

public static void method1(Consumer<Integer> consumer){
    System.out.println("Inside Consumer");
}

public static void method1(Predicate<Integer> predicate){
    System.out.println("Inside Predicate");
}

public static void main(String[] args) {

    List<Integer> lst …
Run Code Online (Sandbox Code Playgroud)

java lambda functional-programming java-8

27
推荐指数
1
解决办法
1583
查看次数

Java无法使用双冒号运算符找到正确的重载方法

当使用双冒号运算符来引用重载方法时,Java似乎无法确定要使用的正确方法.考虑这个例子:

public class A {
    private void setter(final Number value) { }
    private void setter(final Optional<Number> value) { }
    private void setter2(final Optional<Number> value) { }

    private <T> void useSetter(final Consumer<Optional<T>> a) { }

    private void callMethod() {
        useSetter(this::setter); // Error here
        useSetter(this::setter2);
    }
}
Run Code Online (Sandbox Code Playgroud)

第一次调用useSetter不编译并给出以下错误:

Cannot infer type argument(s) for <T> useSetter(Consumer<Optional<T>>)
The type A does not define setter(Optional<Object>) that is applicable here
Run Code Online (Sandbox Code Playgroud)

但是,第二个调用编译得很好,这意味着问题在于重载setter.只有一个setter重载是适用的,所以我不明白为什么这不起作用.

可以通过使用指定参数类型的lambda解决这个问题,但这更详细.

useSetter((final Optional<Number> v) -> setter(v));
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来处理这种情况,或者我是否陷入了这个奇怪的怪癖?

java generics lambda java-8

12
推荐指数
1
解决办法
680
查看次数

Java编译错误:结合重载的方法引用

我有以下类与重载方法:

import java.util.ArrayList;
import java.util.concurrent.Callable;

public abstract class Test {

  public void test1 () {
    doStuff (ArrayList::new); // compilation error
  }

  public void test2 () {
    doStuff ( () -> new ArrayList<> ());
  }

  public abstract void doStuff (Runnable runable);

  public abstract void doStuff (Callable<ArrayList<String>> callable);
}
Run Code Online (Sandbox Code Playgroud)

该方法test1导致错误消息的编译错误 The method doStuff(Runnable) is ambiguous for the type Test.

我添加了第三种方法test3,如下所示:

public void test3 () {
    doStuff ( () -> {
      new ArrayList<> ();
    });
  }
Run Code Online (Sandbox Code Playgroud)

这里doStuff(Runnable) …

java overloading compiler-errors java-8 method-reference

11
推荐指数
1
解决办法
238
查看次数

编译器不推断System.out :: println功能接口

我有一个重载方法,它将两个不同的功能接口作为参数(Runnble和Supplier).System.out.println显然只是兼容Runnable,因为它是一种void方法.然而,编译器仍然声称呼叫是模糊的.怎么可能?

import java.util.function.Supplier;

public class GenericLambdas {
    public static void main(String[] args) {
        wrap(System.out::println);   // Compiler error here
        wrap(() -> {});              // No error
        wrap(System.out::flush);     // No error
    }

    static <R> void wrap(Supplier<R> function) {}

    static void wrap(Runnable function) {}
}
Run Code Online (Sandbox Code Playgroud)

编译器输出:

Error:Error:line (5)java: reference to wrap is ambiguous
    both method <R>wrap(java.util.function.Supplier<R>) in GenericLambdas and method wrap(java.lang.Runnable) in GenericLambdas match 
Error:Error:line (5)java: incompatible types: cannot infer type-variable(s) R
    (argument mismatch; …
Run Code Online (Sandbox Code Playgroud)

java lambda type-inference java-8 functional-interface

8
推荐指数
1
解决办法
1289
查看次数