3

java.util.function.BiFunctions のペアを値にマッピングするから、そのマッピングを反映Enumする を構築したいと考えています。EnumMap

たとえば、letE1E2be はenum型であり、T任意の型です。

 BiFunction<E1,E2, T> theBiFunction = //...anything

 EnumMap<E1,EnumMap<E2,T>> theMap = 
    buildTheMap(                     // <--  this is where the magic happens
                E1.values(), 
                E2.values(),
                theBiFunction);

タイプE1E2

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

「魔法」が発生するメソッドの最適な (よりエレガントで効率的ななど) 実装は何ですか?

4

2 に答える 2

5

一般的なソリューションに行き、それを分解すると、洗練されたソリューションが得られます。まず、 a から を作成する一般的な関数をEnumMap実装し、それ自体と組み合わせた最初の関数を使用して、Functiona のネストされたマッピングを実装します。BiFunction

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

ここに小さなテストケースがあります:

enum Fruit {
    APPLE, PEAR
}
enum Color {
    RED, GREED, YELLOW
}

…</p>

EnumMap<Fruit, EnumMap<Color, String>> result
  =biFuncToMap((a,b)->b+" "+a,
     Fruit.class, Color.class, Fruit.values(), Color.values());
System.out.println(result);

→</p>

{APPLE={RED=RED APPLE, GREED=GREED APPLE, YELLOW=YELLOW APPLE}, PEAR={RED=RED PEAR, GREED=GREED PEAR, YELLOW=YELLOW PEAR}}

もちろん、一般的なソリューションを使用してenum、パラメーターを必要としない具象型のメソッドを構築できClassます…</p>


(Bi)Function提供されたものがスレッドセーフである場合、これは並列ストリームでスムーズに動作するはずです。

于 2014-07-31T17:23:20.850 に答える