Возврат другой анонимной функции в лямбда-выражении java - PullRequest
1 голос
/ 12 марта 2020

Можно ли вернуть другую функцию в лямбда-выражении в java? Скажем, у меня есть следующие лямбда-выражения

addFive = (x) -> x+5;
addFiveIfPositive = (y) -> {
    if (y > 0) return addFive;
    else return y;
};

Чтобы дать некоторый контекст позади, я спрашиваю это, я работаю с лямбда-выражениями, чтобы определить компараторы, и для некоторых компараторов, я хочу «связать» компараторы, которые Я уже определил не писать тот же код снова, учитывая некоторые условия, как в примере выше.

Любая помощь будет оценена.

Редактировать: Это более представительный пример того, что Я работаю с

import java.util.Comparator;

class Random{
    Integer val;
    String str;

    Random(int val, String str){
      this.val = new Integer(val);
      this.str = str;
    }
}

public class Temp{

  static Comparator<Random> c1 = (r1, r2) -> (r1.val).compareTo((r2.val));
  static Comparator<Random> c2 = (r1, r2) -> {
    if ((r1.str).compareTo((r2.str)) == 0){
      return c1.apply(r1,r2);
    }
    return (r1.str).compareTo((r2.str));
  };

  public static void main(String args){
    Random rand1 = new Random(1, "Hello");
    Random rand2 = new Random(2, "Hello");
    System.out.println(c2.compare(rand1, rand2));
  }
}

Использование .apply () дает мне ошибку

Temp.java:18: error: cannot find symbol
      return c1.apply(r1,r2);
               ^
  symbol:   method apply(Random,Random)
  location: variable c1 of type Comparator<Random>

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Согласно редактированию, все, что вам нужно, это использовать:

Comparator<Random> c1 = Comparator.comparing(Random::getVal);
Comparator<Random> c2 = Comparator.comparing(Random::getStr).thenComparing(c1);;

, потому что у вас уже есть Comparator s, поддерживающие вариант использования цепочки с thenComparing API , Обратите внимание, что это просто упрощение следующего кода:

Comparator<Random> c1 = (r1, r2) -> (r1.val).compareTo((r2.val));
Comparator<Random> c2 = (r1, r2) -> {
    if ((r1.str).compareTo((r2.str)) == 0){
        return c1.compare(r1,r2); //'compare' instead of 'apply'
    }
    return (r1.str).compareTo((r2.str));
};

До редактирования вы могли использовать троичный оператор для представления условия, такого как:

IntFunction<Integer> addFive = x -> x + 5;
IntFunction<Integer> addFiveIfPositive = y -> y > 0 ? y + 5 : y;
2 голосов
/ 12 марта 2020

Ты уже почти там - ты просто упускаешь одну вещь; внутри addFiveIfPositive вам нужно вернуть результат применения addFive, а не саму функцию. Это легко сделать, все что вам нужно - это return addFive.apply(y); вместо return addFive;

См. Фрагмент ниже:

import java.util.function.IntFunction;

class Scratch {
    public static void main(String[] args) {
        System.out.println(doStuff(5));
        System.out.println(doStuff(-1));
    }

    public static int doStuff(int val) {

        IntFunction<Integer> addFive = (x) -> x+5;
        IntFunction<Integer> addFiveIfPositive = (y) -> {
            if (y > 0) return addFive.apply(y);
            else return y;
        };

        return addFiveIfPositive.apply(val);
    }
}

Выходы:

10
-1
...