简体   繁体   English

Java 如何传递一个BiFunction作为参数

[英]Java how to pass a BiFunction as a parameter

I need help figuring out how to pass this BiFunction我需要帮助弄清楚如何通过这个 BiFunction

BiFunction<Integer, List<Integer>, Integer> func = (a, b) -> {
        int result = 0;
        int temp = 0;
        for(Integer ele : b) {
            temp = b.get(ele);
            result += temp;
        }
        return a + result;
    };

I am using this junit test我正在使用这个 junit 测试

void testFoldLeft() {
        LinkedList<Integer> l = new LinkedList<>();
        for(int i = 0; i < 10; i++) l.addFirst(i+1);
        Integer u = fp.foldLeft(0, l, func(0,l));
    }

I am attempting to pass the BiFunction func through foldLeft, which looks like this我试图通过 foldLeft 传递 BiFunction func,看起来像这样

static <U,V> V foldLeft(V e, Iterable<U>l, BiFunction<V,U,V> f){
    return null;
}

What func is supposed to do is to take a list, in this case b, sum up all the elements in b then add that number to a and return the result. func 应该做的是获取一个列表,在本例中为 b,将 b 中的所有元素相加,然后将该数字添加到 a 并返回结果。 However, Eclipse gives me an error stating that func is undefined.但是,Eclipse 给了我一个错误,指出 func 未定义。 I'm new to BiFunctions so I'm kind of stuck here.我是 BiFunctions 的新手,所以我有点卡在这里。 I would appreciate any help.我将不胜感激任何帮助。

I think the mismatch is caused by an incorrect declaration of the second parameter of foldLeft .我认为不匹配是由于foldLeft的第二个参数声明不正确造成的。 If, in your example, Integer is the Iterable 's argument, then your method should be declared like this:如果在您的示例中, IntegerIterable的参数,那么您的方法应该这样声明:

static <U, V> V foldLeft(V e, Iterable<V> l, BiFunction<V, U, V> f) {
    return null;
}

V is the element type of the iterable, not U (which, in this case, would be equivalent to Iterable<V> ). V是可迭代的元素类型,而不是U (在这种情况下,它相当于Iterable<V> )。

Further, your invocation should look like this:此外,您的调用应如下所示:

Integer u = foldLeft(0, l, func);

You can't invoke an expression in Java.您不能在 Java 中调用表达式。 Unless func is declared as a method in visible scope, func() will always be invalid.除非func被声明为可见 scope 中的方法,否则func()将始终无效。


Note that you can simplify your generics by getting rid of U (I don't see a specific need for the type variable for the list type here, but I may be missing some use cases):请注意,您可以通过摆脱U来简化您的 generics (我在这里没有看到列表类型对类型变量的具体需求,但我可能会遗漏一些用例):

static <V> V foldLeft(V e, Iterable<V> l, BiFunction<V, Iterable<V>, V> f) {
    return null;
}

You do not show your implementation of foldLeft , but I'm sure it's going to need to iterate over the list, or at least pass it to f.apply .您没有显示foldLeft的实现,但我确信它需要遍历列表,或者至少将其传递给f.apply So I suppose you can make the function take a List<V> :所以我想你可以让 function 拿一个List<V>

static <V> V foldLeft(V e, List<V> l, BiFunction<V, List<V>, V> f) {
    return f.apply(e, l);
}

Otherwise, calling f.apply(e, l) would fail as Function<Integer, LinkedList<Integer>, Integer> and Function<Integer, Iterable<Integer>, Integer> are incompatible.否则,调用f.apply(e, l)将失败,因为Function<Integer, LinkedList<Integer>, Integer>Function<Integer, Iterable<Integer>, Integer>不兼容。

There are two issues in your code:您的代码中有两个问题:

  1. func(0,l) is a syntax error, just pass func variable as the BiFunction . func(0,l)是语法错误,只需将func变量作为BiFunction No need for providing arguments:无需提供 arguments:

     Integer u = foldLeft(0, l, func);
  2. The generics signature of foldLeft does not match the BiFunction . foldLeft 的BiFunction签名与foldLeft不匹配。 Given the current way it is written, Iterable<U> l makes the compiler infer U as Integer , hence the compiler expects the third argument to be a BiFunction<Integer, Integer, Integer> instead of BiFunction<Integer, List<Integer>, Integer> .鉴于它的当前编写方式, Iterable<U> l使编译器将U推断为Integer ,因此编译器期望第三个参数是BiFunction<Integer, Integer, Integer>而不是BiFunction<Integer, List<Integer>, Integer> To make U match the LinkedList<Integer> , declare it as follows:要使U匹配LinkedList<Integer> ,请将其声明如下:

     static <U extends Iterable<V>, V> V foldLeft(V e, U l, BiFunction<V, U, V> f){ return null; }

Side note: I wonder what the function code is doing:旁注:我想知道 function 代码在做什么:

for(Integer ele : b) {
    temp = b.get(ele);
    result += temp;
}

This is looping over elements of b and treating them as indices.这是循环b的元素并将它们视为索引。 I doubt this is what you want.我怀疑这是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM