How to access enum type of another class? Is there a way to use a String (a map key) as an argument of a method expecting Enum> type?
如果有人能指出我做错了什么,我将非常感激。
我有一个接口IDoubleSource,我在Person类中实现。有一个LinearRegression类,其方法采用IDoubleSource参数,但我将传入Person类。
作为IDoubleSource接口的一部分,必须定义一个名为Variables的枚举和一个名为getDoubleValue(Enum)的方法。下面,我将展示我是如何在Person中完成此操作的,并且枚举类型用于在getDoubleValue()方法中指定switch case。
问题:
1)在LinearRegression中,有一个方法computeScore((MultiKeyCoefficient)Map,IDoubleSource),其中最后一个参数是一个接口。尽管将接口导入LinearRegression类,我似乎无法访问computeScore方法中IDoubleSource实现实例的变量枚举。它只是没有注册IDoubleSource有一个名为Variables的枚举(虽然我可以调用getDoubleValue()方法)。有什么我明显做错了,这阻止我访问枚举变量?
2)Person类中的getDoubleValue(Enum)方法旨在返回一个double值,该值取决于传递给它的枚举变量的值。通过循环遍历LinearRegression类中(MultiKeyCoefficient)Map的键(String类型),我想使用键来指定我想要的枚举值作为LinearRegression类中getDoubleValue(Enum)的参数(我希望getDoubleValue()根据它在循环中收到的Enum值返回几个不同的值)。但是,我不能使用(String)键代替预期的枚举,因为我得到一个ClassCastException java.lang.String无法强制转换为java.lang.Enum。如何使用地图的键来指定枚举?
我不太熟悉在Java中使用Enum类型,这可能是我的问题的很大一部分。
现在代码详细信息:
我实现了以下界面:
IDOUBLESOURCE接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public interface IDoubleSource { public enum Variables { Default; } /** * Return the double value corresponding to the given variableID * @param variableID A unique identifier for a variable. * @return The current double value of the required variable. */ public double getDoubleValue(Enum< ? > variableID); } |
通过创建类:
人类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class Person implements IDoubleSource { public enum Variables { nChildren, durationInCouple, ageDiff; } public Person() { ... } public double getDoubleValue(Enum< ? > variableID) { switch ((Variables) variableID) { case nChildren: return getNChildren(); case durationInCouple: return (double)getDurationInCouple(); case ageDiff: return getAgeDiff(); default: throw new IllegalArgumentException("Unsupported variable"); } |
在另一个包中,我有一个类:
LINEARREGRESSION CLASS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public class LinearRegression private MultiKeyCoefficientMap map = null; public LinearRegression(MultiKeyCoefficientMap map) { this.map = map; } .... public double score(IDoubleSource iDblSrc) { return computeScore(map, iDblSrc); } public static double computeScore(MultiKeyCoefficientMap coeffMap, IDoubleSource iDblSrc) { try { final Map<String, Double> varMap = new HashMap<String, Double>(); for (Object multiKey : coeffMap.keySet()) { final String key = (String) ((MultiKey) multiKey).getKey(0); Enum< ? > keyEnum = (Enum< ? >) key; //Throws class cast exception double value = iDblSrc.getDoubleValue(keyEnum); varMap.put(key, value); } return computeScore(coeffMap, varMap); } catch (IllegalArgumentException e) { System.err.println(e.getMessage()); return 0; } } } public static double computeScore(MultiKeyCoefficientMap amap, Map<String, Double> values) { //Do some stuff } |
我非常感谢你花时间阅读这段代码。如果你知道我做错了什么,请告诉我!
非常感谢和祝福,
[R
这里有很多问题:
鉴于这两件事,并且您似乎想要为子类型特定类型的事物选择不同的处理,那么在最坏的情况下,您可以将字符串键作为参数传递,然后在内部改变逻辑。但实际上,您已经提出了一个方案,您需要了解子类型才能请求适当的(支持的)处理。这不允许在使用接口/实现类时使用的解耦类型。您可能希望在此处查看目标并制定出更好的设计。
您所拥有的关键错误假设是
当类(如
所以你可以改变你的界面:
1 2 3 4 5 6 7 | public interface IDoubleSource { public enum Variables { Default; } public double getDoubleValue(Variables variableID); } |
...但是传递给
我认为你真正想做的是声明
1 2 3 4 5 | public interface IDoubleSource<T extends Variables & Enum< T >> { public interface Variables { } public double getDoubleValue(T variableID); } |
你在这里说的是
然后你的实现看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Person implements IDoubleSource<PersonVariables> { public enum PersonVariables implements Variables { nChildren, durationInCouple, ageDiff; } public double getDoubleValue(PersonVariables variableID) { switch (variableID) { //no cast necessary here! case nChildren: // ... default: // this is now really impossible // if the rest of your program has no unsafe casts throw new IllegalArgumentException("Unsupported variable"); } } } |
最后一个技巧是增强
1 2 3 | public static <T extends IDoubleSource.Variable & Enum< T >> double computeScore(MultiKeyCoefficientMap<T,?> coeffMap, IDoubleSource< T > iDblSrc); |
然后地图中的键根本不是