如何构建可复制Java Lambda API中的功能的映射 [英] How to build a Map that replicates a Function in Java's Lambda API
问题描述
从将一对Enum
映射为一个值的java.util.function.BiFunction
中,我想构建一个反映该映射的EnumMap
.
From a java.util.function.BiFunction
that maps a pair of Enum
s into a value, I want to build a EnumMap
that reflects that mapping.
例如,让E1
和E2
为enum
类型,而T
为任何给定类型:
For instance, let E1
and E2
be enum
types and T
any given type:
BiFunction<E1,E2, T> theBiFunction = //...anything
EnumMap<E1,EnumMap<E2,T>> theMap =
buildTheMap( // <-- this is where the magic happens
E1.values(),
E2.values(),
theBiFunction);
给出类型为E1
和E2
的任何一对值
Given any pair of values of type E1
and E2
E1 e1 = //any valid value...
E2 e2 = //any valid value....
以下两个值均应相等:
T valueFromTheMaps = theMap.get(e1).get(e2);
T valueFromTheFunction = theBiFunction.apply(e1,e2);
boolean alwaysTrue = valueFromTheMaps.equals(valueFromTheFunction);
发生"魔术"的方法的最佳实现方式(更优雅,更有效等)是什么?
What's the best (more elegant, efficient, etc...) implementation for the method where the "magic" takes place?
推荐答案
如果您使用通用解决方案并将其分解,则会得到一个优雅的解决方案.首先,实现一个从Function
中创建EnumMap
的通用函数,然后使用第一个与自身结合的函数实现BiFunction
的嵌套映射:
You get an elegant solution if you go to a generic solution and break it down. First, implement a generic function which creates an EnumMap
out of a Function
, then implement the nested mapping of a BiFunction
using the first function combined with itself:
static <T,E extends Enum<E>>
EnumMap<E,T> funcToMap(Function<E,T> f, Class<E> t, E... values) {
return Stream.of(values)
.collect(Collectors.toMap(Function.identity(), f, (x,y)->x, ()-> new EnumMap<>(t)));
}
static <T,E1 extends Enum<E1>,E2 extends Enum<E2>>
EnumMap<E1,EnumMap<E2,T>> biFuncToMap(
BiFunction<E1,E2,T> f, Class<E1> t1, Class<E2> t2, E1[] values1, E2[] values2){
return funcToMap(e1->funcToMap(e2->f.apply(e1, e2), t2, values2), t1, values1);
}
这是一个小测试用例:
Here’s a little test case:
enum Fruit {
APPLE, PEAR
}
enum Color {
RED, GREED, YELLOW
}
...
EnumMap<Fruit, EnumMap<Color, String>> result
=biFuncToMap((a,b)->b+" "+a,
Fruit.class, Color.class, Fruit.values(), Color.values());
System.out.println(result);
→
{APPLE={RED=RED APPLE, GREED=GREED APPLE, YELLOW=YELLOW APPLE}, PEAR={RED=RED PEAR, GREED=GREED PEAR, YELLOW=YELLOW PEAR}}
当然,使用通用解决方案,您可以为不需要Class
参数的具体enum
类型构建方法……
Of course, using the generic solution you can built methods for concrete enum
types which do not require the Class
parameter(s)…
如果提供的(Bi)Function
是线程安全的,则这应该可以与并行流一起平稳地工作.
This ought to work smoothly with a parallel stream if the provided (Bi)Function
is thread safe.
这篇关于如何构建可复制Java Lambda API中的功能的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!