持有具有不同数量的args的函数图

问题描述 投票:0回答:2

[我正在尝试编写一个实用程序类,该实用程序类可以包含StringClass<?>,并返回实际上是该Object的类型化实例的String

例如,如果我有字符串"FALSE"和类"java.lang.Boolean",我想返回键入的Boolean.FALSE。等其他类,例如String,Long,Int,Enum等。

我想以一种在添加新类型时不需要太多重写的方式来执行此操作。目前,我有一个签名为Object getTypedValue(Class<?> clazz, String value);的方法。

[从这里,我以为我可以使用Map<Class<?>, Function<String, Object>>。对于像String和Boolean这样的情况,这很好用,但是对于Enum,我也需要类名。因此,映射变为Map<Class<?>, BiFunction<String, Class<?>, Object>>

但是大多数方法不需要Class参数。还发现了一个新的FunctionalInterface,如:

@FunctionalInterface
public interface OptionalClassFunction<T, CLAZZ, R> {

  R apply(T t, CLAZZ... clazz);

}

当我通过仅以T作为lambda的方法时,似乎不起作用。

例如

ImmutableMap.of(
  Boolean.class, Util::toBoolean
)

private Boolean toBoolean(String value);

不起作用。

关于如何处理的任何建议:

Map<Class<?>, WhateverFunction<String, MAYBE_A_CLASS, Object>>吗?

示例方法为:

  public static Boolean toBoolean(String value) {
    // derive bool
  }

  public static Enum toEnum(String value, Class<?> fieldType) {
    // derive enum
  }
java design-patterns functional-programming functional-interface
2个回答
0
投票

为什么您需要枚举的类名?

例如DayOfWeek是一个DayOfWeek,并且与其他所有enum类一样,它具有enum方法,因此只需注册以下内容:

valueOf(String name)

[如果您不喜欢valueOf(String name)方法,例如因为它区分大小写,并且您的DayOfWeek.class, DayOfWeek::valueOf 方法更好,所以请编写一个辅助方法来封装它,例如

valueOf

然后您使用以下方式注册:

toEnum

助手很好,但是您实际上并不需要它:

public static <T extends Enum<T>> Function<String, T> getEnumParser(Class<T> type) {
    return s -> toEnum(s, type);
}

public static <T extends Enum<T>> T toEnum(String value, Class<T> type) {
    for (T constant : type.getEnumConstants())
        if (constant.name().equalsIgnoreCase(value))
            return constant;
    throw new IllegalArgumentException("Unknown constant for enum " + type.getName() + ": \"" + value + "\"");
}

除非与DayOfWeek.class, Util.getEnumParser(DayOfWeek.class) 一起使用可能会使编译器感到困惑。该帮助程序解决了潜在的编译器推断问题。


0
投票

关于如何处理的任何建议:

DayOfWeek.class, s -> Util.toEnum(s, DayOfWeek.class)

总是将其设为ImmutableMap.of(...),而只需忽略Map<Class<?>, WhateverFunction<String, MAYBE_A_CLASS, Object>> 参数:

BiFunction

由于地图的用户将不知道是否需要Class<?>参数,因此它必须始终传递值,例如

Map<Class<?>, BiFunction<String, Class<?>, Object>> map = Map.of(
        Boolean.class, (s,t) -> Util.toBoolean(s),
        Enum.class, Util::toEnum
);

简体。通常在Class<?>调用后检查是否为null。

当然,这也不起作用,因为呼叫者认为类型是Class<?> type = ... String value = ... Object obj = map.get(type).apply(value, type); ,因此,如果调用方执行get(),查找将失败。现在,调用者所需的逻辑突然变得复杂。

解决方案是将DayOfWeek逻辑封装在一个辅助方法中,因此您可以将type = DayOfWeek.class替换为get-apply来进行地图查找,但是如果这样做,您可能还直接构建了对枚举,绕过地图,并以DayOfWeek.class离开地图。

© www.soinside.com 2019 - 2024. All rights reserved.