具有可从方法调用的三个参数的Java函数

时间:2019-07-05 17:19:10

标签: java function lambda java-stream

我有这种方法,可以调用多个API并汇总所有结果,然后将它们返回到Map中,其中每组结果都与目标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();
};

我看过这里提到的类似内容:Can a java lambda have more than 1 parameter? 但是BiFunctions的示例仅显示它们被用作lambda,因此从外部函数调用(根据我所能找到的),它们将无法工作。 同样,当谈到创建新的FunctionalInterface时,我不确定要在所需功能中使用新接口到底需要什么。

任何想法都很棒。

2 个答案:

答案 0 :(得分:1)

已修改以反映示例

首先,定义一些必需的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创建一个映射,然后采用这些相同的键并将它们应用于参数列表。那就是地图的价值。

根据初始流类型,您可能需要使用mapToObjmap代替上面的boxed()方法。

答案 1 :(得分:1)

功能接口(简单来说)是一种方法的接口。

您想要用@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);
}