Lambda的转换:BiConsumer <Integer,Integer>

时间:2019-06-26 06:58:03

标签: java lambda

我遇到这样的编译器故障:  BiConsumer类型的accept方法(Integer,Integer)不适用于参数(Object,Object)。我该如何强制转换两个Integer输入,以便编译器将它们接受为<Integer, Integer>

我在以下代码中遇到了失败:

import java.util.function.BiConsumer;

public class ExceptionHandlingExample {

    public static void main(String[] args) {
        int[] numberArray = { 1, 2, 3, 4 };
        int key = 2;
        calc(numberArray, key, wrapperForLambda( (a, b) -> System.out.println(a / b) ));
        // Type Safety: The expression of Type BiConsumer needs unchecked conversion to conform to unchecked BiConsumer<Integer, Integer>
    }

    private static void calc(int[] numberArray, int key, BiConsumer<Integer, Integer> consumer) {
        for (int i : numberArray) {
            consumer.accept(i, key);
        }
    }

    private static BiConsumer wrapperForLambda(BiConsumer<Integer, Integer> consumer) {
    // BiConsumer is a raw type. References to generic type BiConsumer<T, U> should be parameterized       
        return (a, b) -> consumer.accept(a, b) ;   
    // [Compilier-error] The method accept (Integer, Integer) in the type BiConsumer<Integer, Integer> is not applicable for the arguments (Object, Object) 
    }
}

我想摆脱编译器错误: BiConsumer类型的accept方法(Integer,Integer)不适用于参数(Object,Object)

谢谢您的帮助!

4 个答案:

答案 0 :(得分:2)

请勿使用原始类型BiConsumer。将方法声明为

private static BiConsumer<Integer, Integer> 
        wrapperForLambda(BiConsumer<Integer, Integer> consumer) {   
    return (a, b) -> consumer.accept(a, b);
}

使用原始BiConsumer时,Java会将其用作lambda表达式(a, b) -> consumer.accept(a, b)的目标类型。这样做的结果是,假设参数ab的类型为Object(原始类型,请记住!),它不适用于您的consumer BiConsumer,期望Integer s。

如果这应该是通用方法,则可以使该方法通用:

private static <T, U> BiConsumer<T, U> 
        wrapperForLambda(BiConsumer<T, U> consumer) {   
    return (a, b) -> consumer.accept(a, b);
}

答案 1 :(得分:2)

我不知道wrapperForLambda的目的是什么。不用了只需按以下方式调用calc

calc(numberArray, key, (a, b) -> System.out.println(a / b));

wrapperForLambda中的错误可以通过以下方法消除:

private static BiConsumer wrapperForLambda(BiConsumer<Integer, Integer> consumer) {
     return consumer;
}

但是我仍然认为这种方法毫无意义。

P.S。我假设calc方法中的循环应该在someNumbers数组而不是numberArray(这是main方法的局部变量)上进行迭代。

答案 2 :(得分:0)

您可以用作

    return (a, b) -> consumer.accept((Integer) a, (Integer) b);

在Java 1.5之前,您甚至无法做到这一点:

    int a;

    Object x = (Integer) a;

编译器会抱怨a是原始数据类型,因此不能转换为对象。

从Java 1.5开始,Java引入了自动装箱的概念。因此,以下操作就可以了:

    int a;

    Object x = (Integer) a;

因为编译器知道如何自动从原始int转换为框式Integer;从整数到对象,这不是问题。

但是,您要做什么:

    int a;

    Object x = (int) a;

基本上是在告诉编译器避免装箱。您明确地告诉编译器将a保留为int,并将对该int的引用放入Object中。编译器并非旨在处理这种情况。

答案 3 :(得分:0)

您不需要@Eran正确提及的方法wrappedForLambda

只需直接使用lambda表达式即可。

public static void main(String[] args) {
    int[] numberArray = { 1, 2, 3, 4 };
    int key = 2;
    calc(numberArray, key, (a, b) -> System.out.println(a / b) );
    // Type Safety: The expression of Type BiConsumer needs unchecked conversion to conform to unchecked BiConsumer<Integer, Integer>
}

private static void calc(int[] someNumbers, int key, BiConsumer<Integer, Integer> consumer) {
    for (int i : numberArray) {
        consumer.accept(i, key);
    }
}

如果由于某种原因(旧的JDK或旧的eclipse)无法编译,则将其显式转换为Integer:

calc(numberArray, key, (Integer a, Integer b) -> System.out.println(a / b) );