我想创建一个(键,函数)的映射,以便我可以获得一个特定键的正确功能,其中'key'是字符串。该函数采用(键,值)的映射,两者都是字符串,返回ExtractedParam类型的结果。
这是ExtractedParam类
class ExtractedParams<T> {
String key;
Optional<T> value;
String errorMessage;
public ExtractedParams(String key, Optional<T> value, String message) {
this.key = key;
this.value = value;
this.errorMessage = message;
}
public Optional<T> getValue() { return value;}
}
这是具有主要方法和功能的类
public class Spike {
private static Function< Map<String,String>, ExtractedParams<String> > typeExtractor = (m) -> {
if (!m.containsKey("type")) {
return new ExtractedParams<>("type", Optional.empty(), "type is a mandatory parameter");
}
String dt = m.get("type");
return new ExtractedParams<>("type", Optional.of(dt), null);
};
private static Function< Map<String,String>, ExtractedParams<Integer> > valueExtractor = (m) -> {
if (!m.containsKey("v")) {
return new ExtractedParams<>("v", Optional.empty(), "v is a mandatory parameter");
}
Integer v = 0;
try {
v = Integer.parseInt(m.get("v"));
}
catch (NumberFormatException e) {
return new ExtractedParams<>("v", Optional.<Integer>empty(), "v is a number");
}
return new ExtractedParams<>("v", Optional.of(v), null);
};
private static Map<String, Function<Map<String, String>, ExtractedParams<? extends Object> > > paramFunctionMapper = new HashMap();
public static void main(String[] args) {
paramFunctionMapper.put("type", typeExtractor); // compiler error
paramFunctionMapper.put("value", valueExtractor); // compiler error }
}
}
正如您所看到的,我正在尝试为哈希映射的键添加特定函数。但是编译器将其标记为错误,表示'put'方法的第二个参数不是',ExtractedParams',而是',ExtractedParams'(在第一次放置的情况下)
我一直以为ExtractedParams应该允许ExtractedParams或ExtractedParams。
这里有什么问题?请帮我理解。
(UPDATE)使用上面的ExtractParams类编译
public static void main(String[] args) {
Map< String, ExtractedParams<? extends Object>> map = new HashMap<>();
map.put("type",new ExtractedParams<String>("dt", Optional.of("number"), ""));
map.put("value",new ExtractedParams<Integer>("value", Optional.of(4), ""));
}
答案 0 :(得分:3)
虽然E<String>
是E<? extends Object>
的子类,但F<E<String>>
不是F<E<? extends Object>>
的子类。
正如您必须E<? extends Object>
使其成为E<String>
的超级类,所以您必须F<? extends E<? extends Object>>
。
如果您将地图声明为Map<String, Function<Map<String, String>, ? extends ExtractedParams<? extends Object>>>
,则会进行编译。
或者,您可以使用通配符声明函数:
private static Function< Map<String, String>, ExtractedParams<?>> valueExtractor = ....
而且,最可读的方法可能是将提取器声明为方法,然后使用方法引用:
static ExtractedParams<String> getType(Map<String, String> m) {
.....
}
Map<String, Function<Map<String, String>, ExtractedParams<?>>> mapper = new HashMap<>();
mapper.put("type", Spike::getType);