简体   繁体   English

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

[英]Java Function with three parameters callable from methods

I have this method that calls multiple APIs and aggregates all the results and returns them in a Map where each set of results is matched to the target API so that they can be grouped and displayed properly in a service. 我有这个方法,可以调用多个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;
}

I have now have to refactor this code so that for example API 1 - 3 can be called in one function and then API 4 - N can be called from another function. 我现在必须重构此代码,以便可以在一个函数中调用例如API 1-3,然后可以从另一个函数中调用API 4-N。 The functions will be called from different methods so I need to move this function out of this method and then pass in the QueryParams object in as another parameter to the function but then I run into the issue of the Function not being able to accept more than one parameter. 这些函数将通过不同的方法进行调用,因此我需要将该函数移出该方法,然后将QueryParams对象作为另一个参数传递给该函数,但随后遇到的问题是该函数不能接受超过一个参数。 Eg 例如

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();
};

I have seen something similar mentioned here: Can a java lambda have more than 1 parameter? 我在这里看到了类似的内容: java lambda可以有多个参数吗? But the examples of BiFunctions only show them being used as lambdas and so wont work when being called by an external method, from what I have been able to find. 但是BiFunctions的示例仅显示它们被用作lambda,因此从外部函数调用(根据我所能找到的),它们将无法工作。 Also when it talks about creating a new FunctionalInterface I'm not sure what exactly is needed to be able to use the new interface in my required functions. 同样,当谈到创建新的FunctionalInterface时,我不确定要在我所需的功能中使用新接口到底需要什么。

Any ideas would be great. 任何想法都很棒。

Modified to reflect example 修改以反映示例

First, define some required BiFunction 首先,定义一些必需的BiFunction


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


Now define some data. 现在定义一些数据。

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

Now apply the mapping function. 现在应用映射功能。


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

The above takes the stream and creates a map with the data acting as the keys and then takes those same keys and applies them to function with the parameter list. 上面的方法获取stream并创建一个以数据为keys的映射,然后获取这些相同的键并将其应用于参数列表。 That becomes the value of the map. 这就是地图的价值。

You will probably need to use mapToObj or map in place of the boxed() method above depending on the initial stream type. 根据初始流类型,您可能需要使用mapToObjmap来代替上述boxed()方法。

A functional interface is (in simple terms) an interface with one method. 功能接口(简单而言)是一种方法的接口。

You'd want to annotate the interface with @FunctionalInterface to document its purpose, and to ensure nobody accidentally adds another method. 您需要使用@FunctionalInterface注释接口以记录其用途,并确保没有人不小心添加其他方法。

The name of the method doesn't really matter, but should of course be appropriate for what it's supposed to do. 方法的名称并不重要,但是当然应该适合它应该做的事情。

So, if you need a function with 3 parameters, create your own functional interface. 因此,如果您需要一个带有3个参数的函数,请创建自己的函数接口。 You can make it specific or or make it general purpose using generic type arguments. 您可以使用泛型类型参数使它特定或通用。

@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);
}

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

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