Java как передать функцию BiFunction в качестве параметра - PullRequest
1 голос
/ 18 апреля 2020

Мне нужна помощь, чтобы выяснить, как пройти эту 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;
    };

Я использую этот тест 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));
    }

Я пытаюсь передать забаву BiFunction c через foldLeft , который выглядит следующим образом:

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

То, что должен сделать c, это взять список, в данном случае b, суммировать все элементы в b, затем добавить это число в a и вернуть результат. Тем не менее, Eclipse дает мне ошибку, утверждая, что fun c не определено. Я новичок в BiFunctions, поэтому я застрял здесь. Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

В вашем коде есть две проблемы:

  1. func(0,l) - синтаксическая ошибка, просто передайте func переменную как BiFunction. Не нужно указывать аргументы:

    Integer u = foldLeft(0, l, func);
    
  2. Общая сигнатура foldLeft не соответствует BiFunction. Учитывая текущий способ написания, Iterable<U> l делает компилятор выводящим U как Integer, следовательно, компилятор ожидает, что третий аргумент будет BiFunction<Integer, Integer, Integer> вместо BiFunction<Integer, List<Integer>, Integer>. Чтобы U соответствовало LinkedList<Integer>, объявите его следующим образом:

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

Примечание: интересно, что делает код функции:

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

Это цикл по элементам b и обработка их как индексов. Я сомневаюсь, что это то, что вы хотите.

0 голосов
/ 18 апреля 2020

Я думаю, что несоответствие вызвано неправильным объявлением второго параметра foldLeft. Если в вашем примере Integer является аргументом Iteratble, то ваш метод должен быть объявлен так:

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

V - это тип элемента итерируемого, а не U (что в данном случае эквивалентно Iterable<V>).

Кроме того, ваш вызов должен выглядеть следующим образом:

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

Вы не можете вызвать выражение в Java. Если func не объявлен как метод в видимой области видимости, func() всегда будет недействительным.


Обратите внимание, что вы можете упростить свои генерики, избавившись от U (я не вижу определенная c потребность в переменной типа для типа списка здесь, но я могу пропустить некоторые варианты использования):

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

Вы не показываете свою реализацию foldLeft, но я конечно, нужно будет перебрать список или, по крайней мере, передать его f.apply. Поэтому я полагаю, что вы можете заставить функцию принимать List<V>:

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

В противном случае вызов f.apply(e, l) завершится неудачно, поскольку Function<Integer, LinkedList<Integer>, Integer> и Function<Integer, Iterable<Integer>, Integer> несовместимы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...