问候,我有一些定义如下的功能:
@RequestMapping(value = "/getWeek", method = RequestMethod.GET)
public ResponseEntity<?> getAvgWeek(BigInteger id) {
List<TimePeriodCalc> result = Calc.getWeek(id);
return new ResponseEntity<>(result, HttpStatus.OK);
}
并且
@RequestMapping(value = "/getMonth", method = RequestMethod.GET)
public ResponseEntity<?> getAvgMonth(BigInteger id) {
List<TimePeriodCalc> result = Calc.getMonth(id);
return new ResponseEntity<>(result, HttpStatus.OK);
}
也许getYear,getQuarter,getDate ....
现在我想将它们组合起来并添加一个参数来告诉我需要返回什么。 现在的问题是我必须定义switch case语句,这可能会使我的代码冗长且不专业。 无论如何我可以像这种情况一样使用Lambda表达式:
HashMap<String, Runnable> myMap = .... (declare and input some values)
myMap.put("executeA", () -> funA())
myMap.get("executeA")
然后我的代码看起来像:
result = myMap.get("week");
//Or any kinds of assignment, the map does not have to return a list
或:
result = myMap.get("year");
依旧......
谢谢。
答案 0 :(得分:3)
假设getWeek
,getMonth
等方法都采用相同的单个参数(BigInteger
,根据您的评论),您可以创建Map
映射字符串到Function<BigInteger, List<TimePeriodCalc>>
并使用静态方法引用填充此地图...
Map<String, Function<BigInteger, List<TimePeriodCalc>>> myMap = new HashMap<>();
myMap.put("week", Calc::getWeek);
myMap.put("month", Calc::getMonth)
...
...然后从地图中获取正确的函数,并在通用方法中使用apply
:
@RequestMapping(value = "/getAny", method = RequestMethod.GET)
public ResponseEntity<?> getAvgAny(String period, BigInteger id) {
List<TimePeriodCalc> result = myMap.get(period).apply(id)
return new ResponseEntity<>(result, HttpStatus.OK);
}
关于您的评论:对于具有一个参数的函数,Java仅具有Function
,对于两个参数具有BiFunction
,即 x - &gt; y 和(x,y) - &gt; ž。具有两个以上参数的AFAIK函数或方法引用是不可能的。如果必须传递两个以上的参数,则可以使用Supplier
,使用 no 参数,但访问其范围内的变量。但是,这需要在方法中定义Map
:
@RequestMapping(value = "/getAny", method = RequestMethod.GET)
public ResponseEntity<?> getAvgAny(String period, BigInteger id, many other parameters) {
Map<String, Supplier<List<TimePeriodCalc>>> myMap = new HashMap<>();
myMap.put("week", () -> Calc.getWeek(id and many other parameters));
...
List<TimePeriodCalc> result = myMap.get(period).get();
return new ResponseEntity<>(result, HttpStatus.OK);
}
或者您可以将不同的参数包装到Object[]
中并将其传递给函数:
Map<String, Function<Object[], List<TimePeriodCalc>>> myMap = new HashMap<>();
myMap.put("week", p -> Calc.getWeek((BigInteger) p[0], (Some) p[1], (Other) p[2], (Class) p[3]));
...
@RequestMapping(value = "/getAny", method = RequestMethod.GET)
public ResponseEntity<?> getAvgAny(String period, BigInteger id, many other parameters) {
Object[] params = new Object[] {id and many other parameters};
List<TimePeriodCalc> result = myMap.get(period).apply(params);
return new ResponseEntity<>(result, HttpStatus.OK);
}
正如by Holger in comments所指出的,您还可以定义自己的接口,提供具有两个以上参数的单个函数,然后创建Map
个,使用lambda实现该方法并从中映射那些你要调用的函数的参数。
interface MyInterface {
List<TimePeriodCalc> getResult(BigInteger id, some more stuff);
}
Map<String, MyInterface> myMap = new HashMap<>();
myMap.put("week", (id, more, stuff) -> Calc.getweek(id, more, stuff));
...
List<TimePeriodCalc> test = myMap.get("week").getResult(id, more, stuff);