0

我有一个接口 FeatureValue,它实现了一个叫做漂亮打印的函数。

我现在有两个实现该接口的类:FeatureString 和 FeatureList(FeatureList 中的列表包含字符串)。这些类只是包装器,分别存储一个字符串和一个列表,并为其包装的值实现漂亮的打印功能。

我有 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 参数化的,因此需要进行强制转换

4

2 回答 2

0

做你的

public interface FeatureValue
{
    public String prettyPrint();
}

可迭代的,像这样

public interface FeatureValue extends Iterable<String>
{
    public String prettyPrint();
}

这将使FeatureValueforeach 循环可以迭代任何内容。

对于实际上不需要迭代的类,要么抛出异常

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();
   }
}
于 2012-12-19T00:05:06.263 回答
0

将方法添加getValue()到您的界面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;
    }

}

主.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;
}
于 2012-12-18T23:57:09.457 回答