Java 8通用函数映射

时间:2015-05-06 21:01:37

标签: java generics java-8

不确定这是否可行;我承认我并不像我希望的那样擅长仿制药。

基本上,我想创建一个类的地图 - >功能 其中用于键的类是函数输入的类,如此(非法律语法):

chkconfig

所以,如果我这样做:

public static Map<Class<T>,Function<T,Expression>> STUFF = new HashMap<>();

{
    STUFF.put(List.class, ListExpression::new);
    STUFF.put(String.class, StringExpression::new);// this constructor must take string
}

它适合我的类型。

3 个答案:

答案 0 :(得分:6)

无法做到。每次你想要Map<Class<T>, SomeType<T>>时,即将一个类与参数化类型相关联,以某种方式与键中的类相关,就无法完成。这是因为密钥类型Class<T>必须按照Map<K, V>定义在所有条目之间共享。

剩下的是具有Map<Class<?>, SomeType<?>>的实际替代方法,将此地图封装在私有字段中,并在将项目放入地图时检查约束。像

这样的东西
public class StuffManager {

  private final Map<Class<?>, Consumer<?>> stuff = new HashMap<>();

  public <T> void register(Class<T> key, Consumer<? super T> val) {
    stuff.put(key, val);
  }
}

答案 1 :(得分:3)

如果您使用Guava&#39; TypeToken之类的东西,那么您可以以类型安全的方式执行此操作但仍未选中。

window.swaggerUi = new SwaggerUi({
        // ...
        sorters : "alpha" // or sorter I've tried both
      });

您可以使用class ExpressionMap { private final Map<TypeToken<?>, Function<?, Expression>> m = new HashMap<>(); <T> void put(TypeToken<T> type, Function<T, Expression> f) { m.put(type, f); } <T> Function<T, Expression> get(TypeToken<T> type) { @SuppressWarnings("unchecked") final Function<T, Expression> f = (Function<T, Expression>) m.get(type); return f; } } static ExpressionMap stuff = ExpressionMap(); static { stuff.put(new TypeToken<List>() {}, ListExpression::new); stuff.put(new TypeToken<String>() {}, StringExpression::new); } 代替Class,但问题是它会因泛型类型而崩溃。

如果你有

TypeToken

您无法ListStringExpression extends Expression { ListStringExpression(List<String> l) {} } ,因此所有Class<List<String>>都会被ListOfSomeTypeExpression::new混为一谈。这不安全。

你可以这样做:

Function<List, Expression>

所以它可能但要注意警告。

另见What is a raw type and why shouldn't we use it?

答案 2 :(得分:1)

不,您无法使用默认的Map界面执行此操作。

但是你当然可以“隐藏”立面背后的地图 - 一个为用户提供特定方法的自定义界面或类:

public <T> Function<T, Expression> getFunction(Class<T> key) {
    // implement using generic Map<Class<?>, Function<?, Expression>
}

甚至:

public Expression apply(Object param);