我有一个FeatureValue接口,它实现了一个名为pretty print的函数。
我现在有两个实现该接口的类:FeatureString和FeatureList(FeatureList中的列表包含字符串)。这些类只是分别存储字符串和列表的包装器,并为它们的包装值实现了漂亮的print函数。
我有EnumMap,它将一些Feature类型的枚举作为键(一些对应于字符串,一些对应于列表)。
我最初创建了这个界面,以便我可以遍历枚举并打印它们。但现在我希望能够从包装器FeatureValue中获取值。
由于我将枚举映射存储为<Feature, FeatureValue>
,因此它不知道包装值是什么类型,所以当我得到它时我必须进行转换。
有没有办法重构我的代码,这样我就不需要进行强制转换,但仍然可以在不知道类型的情况下迭代枚举并打印它们?
枚举
public enum Features
{
KIND("kind"),
RULE("rule"),
PROBLEM("problem"),
private String name;
Features(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
接口
public interface FeatureValue
{
public String prettyPrint();
}
列表实现(FeatureString有一个类似的,我将省略)
public class FeatureList implements FeatureValue
{
private final List<String> list;
public FeatureList(List<String> list)
{
this.list = list;
}
@Override
public String prettyPrint()
{
return Arrays.toString(list.toArray());
}
public List<String> getList()
{
return list;
}
}
投射代码
for(String token: ((FeatureList) enumMap.get(Feature.particularFeatureThatCorrespondsToLists)).getValue())
doSomething(token);
由于地图是针对Feature的值而非FeatureList
的参数化,因此需要进行强制转换答案 0 :(得分:0)
将方法getValue()
添加到您的界面FeatureValue
,并使界面参数化。
FeatureValue.java
public interface FeatureValue<E> {
String prettyPrint();
E getValue();
}
FeatureList.java
public class FeatureList implements FeatureValue<List<String>> {
private final List<String> list = new ArrayList<String>();
public String prettyPrint() {
return list.toString();
}
public List<String> getValue() {
return list;
}
}
Main.java
public static void main( String[] args ) {
for (String each: getAsList(enumMap, Features.KIND)) {
// do stuff
}
}
private static List<String> getAsList(
EnumMap<Features, FeatureValue> enumMap, Features key) {
FeatureValue value = enumMap.get(key);
return value != null ?
((FeatureList) value.getValue()).getValue() : Collections.EMPTY_LIST;
}
答案 1 :(得分:0)
制作你的
public interface FeatureValue
{
public String prettyPrint();
}
可迭代,像这样
public interface FeatureValue extends Iterable<String>
{
public String prettyPrint();
}
这将使任何FeatureValue
可以通过foreach循环进行迭代。
对于实际上不需要迭代的类,要么抛出异常
public class Stubbed1 extends FeatureValue {
public Iterator<String> getIterator() {
throw new UnsupportedOperationException();
}
}
或返回一个空的迭代器
public class Stubbed2 extends FeatureValue {
public Iterator<String> getIterator() {
return Collections.<String>emptyList().iterator();
}
}
对于需要迭代的类,请执行以下操作
public class DocumentFeatureList implements FeatureValue
{
private final List<String> list;
...
public Iterator<String> getIterator() {
return list.iterator();
}
}