Функция Java с тремя параметрами, вызываемыми из методов - PullRequest
0 голосов
/ 05 июля 2019

У меня есть этот метод, который вызывает несколько API, объединяет все результаты и возвращает их на карте, где каждый набор результатов сопоставляется с целевым API, чтобы их можно было сгруппировать и правильно отобразить в службе.

public AggregateResults search(QueryParams params) {
    Stream<APITarget> targets = params.getTargets().parallelStream();

    Function<APITarget, APIResults> func = (APITarget target) -> {
        if (params.length() >= MIN_LENGTH) {
           switch (target) {
               case api1:
                    return searchAPI1(params);
               case api2:
                   return searchAPI2(params);
               .
               .
               case apin:
                    return searchAPIn(params);
            }
        }
        return new APIResults.Builder().build();
    };

    Map<APITarget, APIResults> results = targets.collect(Collectors.toMap(t -> t, func));
    return AggregateResults;
}

Теперь мне нужно провести рефакторинг этого кода, чтобы, например, API 1 - 3 можно было вызывать в одной функции, а затем API 4 - N можно вызывать из другой функции.Функции будут вызываться из разных методов, поэтому мне нужно убрать эту функцию из этого метода, а затем передать объект QueryParams в качестве другого параметра функции, но затем я столкнусь с вопросом о том, что функция не может принять больше, чемодин параметр.Например,

Function<APITarget, APIResults> exampleFunc = (APITarget target, QueryParams params) -> {
    if (params.length() >= MIN_LENGTH) {
        switch (target) {
            case api1:
                return searchAPI1(params);
            case api2:
                return searchAPI2(params);            
        }
    }
    return new APIResults.Builder().build();
};

Я видел нечто подобное, упомянутое здесь: Может ли лямбда-код java иметь более 1 параметра? Но примеры BiFunctions показывают, что они используются только как лямбды и поэтому не работаютпри вызове внешним методом, из того, что я смог найти.Кроме того, когда речь идет о создании нового FunctionalInterface, я не уверен, что именно нужно, чтобы иметь возможность использовать новый интерфейс в моих необходимых функциях.

Любые идеи были бы хорошими.

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Функциональный интерфейс - это (в простом выражении) интерфейс с одним методом.

Вы хотите аннотировать интерфейс с помощью @FunctionalInterface для документирования его назначения и обеспеченияникто случайно не добавляет другой метод.

Название метода на самом деле не имеет значения, но, конечно, должно соответствовать тому, что он должен делать.

Итак, если вам нужна функция с3 параметра, создайте свой собственный функциональный интерфейс.Вы можете сделать его конкретным или универсальным, используя аргументы универсального типа.

@FunctionalInterface
interface TripleString {
    String doStringOp(String a, String b, String c);
}

@FunctionalInterface
interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}
1 голос
/ 05 июля 2019

Изменено в соответствии с примером

Сначала определите некоторые обязательные BiFunction


  BiFunction<Integer, int[], Integer> func = (a, b) ->
      {
         for (int i = 0; i < b.length; i++) {
            a *= b[i];
         }
         return Integer.valueOf(a);
      };


Теперь определим некоторые данные.

      //Stream source
      int[] data = { 10, 20, 30
      };
      // parameter source
      int[] params = { 3, 5, 11
      };
      Convert data to stream
      IntStream targets = Arrays.stream(data);

Теперь примените функцию отображения.


     Map<Integer, Integer> results = targets.boxed().collect(
            Collectors.toMap(t -> t, t -> func.apply(t, params)));
      System.out.println(results);

Приведенный выше код берет stream и создает карту с данными, действующими как keys, а затем берет те же ключи и применяет их для работы со списком параметров. Это становится ценностью карты.

Возможно, вам потребуется использовать mapToObj или map вместо описанного выше boxed() метода в зависимости от начального типа потока.

...