如何构建可复制Java Lambda API中的功能的映射 [英] How to build a Map that replicates a Function in Java's Lambda API

查看:142
本文介绍了如何构建可复制Java Lambda API中的功能的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从将一对Enum映射为一个值的java.util.function.BiFunction中,我想构建一个反映该映射的EnumMap.

From a java.util.function.BiFunction that maps a pair of Enums into a value, I want to build a EnumMap that reflects that mapping.

例如,让E1E2enum类型,而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);

给出类型为E1E2的任何一对值

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆