是一个循环良好风格的枚举开关

时间:2013-05-07 22:01:34

标签: java coding-style enums switch-statement

我遇到了与在Java中实现某些内容相关的问题,我认为Enums是其中的一部分(或者也许只是我使他们成为问题的一部分。

所以问题是我有一个模型类,假设它有3个字段:

class ConferenceInfo {
    String name;
    Date date;
    String location;

    public boolean compareByName(ConferenceInfo other) {
        return getName().equals(other.getName());
    }

    public boolean compareByDate(ConferenceInfo other) {
        return getDate().compareTo(other.getDate()) == 0;
    }

    public boolean compareByLocation(ConferenceInfo other) {
        return getLocation().equals(other.getLocation());
    }
}

我有一组我需要比较的对象列表:

List<Pair<ConferenceInfo, ConferenceInfo>> 

现在,这很容易,如果我可以覆盖一个equals方法,但在这种情况下它有点不同 - 我必须通过它们的字段值比较这些对象并输出它们的数量不同。为了做到这一点,我创建了一个枚举:

public enum FieldType {
    NAME,
    DATE,
    LOCATION
}

并创建了一个方法(在我的Measurement类中,具有前面提到的对列表),它将FieldType作为参数并执行如下操作:

for (Pair<ConferenceInfo, ConferenceInfo> result : results) {
    ConferenceInfo first = result.getFirst();
    ConferenceInfo second = result.getSecond();

    switch (field) {
    case NAME:
        if (!first.compareByName(second)) {
            differentValues++;
        }
        break;
    case DATE:
        if (!first.compareByDate(second)) {
            differentValues++;
        }
        break;
    case LOCATION:
        if (!first.compareByLocation(second)) {
            differentValues++;
        }
        break;
    }
}

它有效,但我想知道我编码它的方式是一个好习惯还是我应该用不同的方式写它...我有点不喜欢在循环中切换,但也许只是我:)

2 个答案:

答案 0 :(得分:4)

你可以使用多态而不是你的开关:

public enum FieldType {
    NAME {
        @Override
        public boolean areEqual(ConferenceInfo c1, ConferenceInfo c2) {
            return c1.compareByName(c2);
        }
    },
    DATE {
        @Override
        public boolean areEqual(ConferenceInfo c1, ConferenceInfo c2) {
            return c1.compareByDate(c2);
        }
    },
    LOCATION {
        @Override
        public boolean areEqual(ConferenceInfo c1, ConferenceInfo c2) {
            return c1.compareByLocation(c2);
        }
    };

    public abstract boolean areEqual(ConferenceInfo c1, ConferenceInfo c2);
}

然后,在你的代码中:

for (Pair<ConferenceInfo, ConferenceInfo> result : results) {
    ConferenceInfo first = result.getFirst();
    ConferenceInfo second = result.getSecond();
    if (!field.areEqual(first, second)) {
        differentValues++;
    }
}

这具有额外的优势,如果出现新的枚举值,您将不会有忘记向开关添加案例的风险。

答案 1 :(得分:-1)

不确定我是否会遗漏某些内容,但在这种情况下,我会在simplemodel类中实现一个方法并检查不同的值:

class SimpleModel  {
     ...

    int differentFields(SimpleModel obj){
        int differentValues = 0;
        if (!this.compareByName(obj)) {
            differentValues++;
        }
        if (!first.compareByDate(second)) {
             differentValues++;
        }
        if (!first.compareByLocation(second)) {
            differentValues++;
        }
        return differentValues;
    }
}

并在比较对的方法中,使用它

for (Pair<ConferenceInfo, ConferenceInfo> result : results) {
    ConferenceInfo first = result.getFirst();
    ConferenceInfo second = result.getSecond();
    first.differentFields(second);
}