枚举与从文件中读取的字符串数组有关

时间:2013-06-18 13:32:27

标签: java arrays string enums

我收到了一份工作代码(Java,1.7),它执行以下操作: 将一个字符串数组(一个血液测试名称列表)从一个文件加载到一个字符串数组成员中(使用Properties和FileInputStream)。该文件可以更改字符串,但含义保持不变(例如:测试可以称为“abc”,而在另一次运行中,它称为“zzz”)。我有一个枚举测试名称的枚举类。枚举字符串与输入的字符串不同(因为后者可以改变)。

文件bloodtest.names包含:

bloodTestNames=abc;def;123;

代码:

public enum BloodTestNames {
AAA,BBB,CCC;    
}

Properties props = new Properties();
FileInputStream fis = new FileInputStream("bloodtest.names");
props.load(fis);
String testName[]=props.getProperty("bloodTestNames").toString().split(";");

现在问题: 问题1: 当我知道测试名称时,我需要返回文件中设置的字符串(例如:返回“def”表示值BBB)。这样做最好的是什么?

我提出的最佳方式是:

return testName[BloodTestNames.BBB.ordinal()]

问题2:如果在编译时不知道BBB - 我如何实现相同的目标?

三点: *我是C的老手,但是是Java的新手。任何做和不欢迎。假设我的Java知识为零。 *我没有完全重新分解,这就是我们需要的东西。 *我可能忘了提到重要的细节,请问,我会感觉到缺失的空白

3 个答案:

答案 0 :(得分:1)

使整个设置驱动:添加一个statuc方法来加载设置的字符串映射到枚举,并添加使用这些设置的工厂方法:

public enum BloodTestNames {
    AAA,BBB,CCC; 
    private static Map<String, BloodTestNames> map = new HashMap<String, BloodTestNames>();

    public static void addAlias(String alias, String name) {
        map.put(alias, valueOf(name));
    }

    public static BloodTestNames getByAluas(String alias) {
        if (map.containsKey(alias))
            return map.get(alias);
        // own name assumed to be mapped
        return valueOf(alias);
    }
}

启动时,根据某些设置文件反复调用BloodTestNames.addAlias()以加载映射。

当您阅读已保存的文件时,请使用BloodTestNames.getByAlias()返回给定字符串值的枚举。


你最好用单数命名你的类,并删除“Name”,即BloodTest - 为每个枚举的名称命名(所有枚举都有一个“名称”,即编码的实例名称) )。

答案 1 :(得分:1)

我首先假设你需要枚举常量来建模这个用例,因为你有一些特定的代码可以为每种血液测试执行(否则,一组简单的字符串就足够了,更灵活,因为您不需要预先知道测试的数量或关心他们的名字。)


Q1:由于Java枚举只是一系列值,你可以充分利用它们面向对象的本质。

public enum BloodTest {
    AAA, BBB, CCC;

    private static String[] names;

    public static void setNames(String[] names) {
        if (BloodTest.names != null)
            throw new IllegalStateException("You can only set the names once");
        if (names.length != values().length)
            throw new IllegalArgumentException("Wrong number of names");
        BloodTest.names = names;
    }

    @Override
    public String toString() {
        return names[ordinal()];
    }
}

现在您需要做的是通过调用BloodTest.setNames(namesFromConfiguration)初始化您的枚举,然后您可以通过调用标准toString()方法获取每个常量的字符串表示形式:BloodTest.BBB.toString()

由于最初的假设是每个测试类型都有一些特定的逻辑,我建议逻辑(以及所需的属性)也将封装在枚举本身或枚举常量中; e.g:

public enum BloodTest {
    AAA(10) {
        @Override
        public boolean isRequired(MedicalRecord medicalRecord) {
            return medicalRecord.includes("someDisease");
        }
    },
    BBB(15) {
        @Override
        public boolean isRequired(MedicalRecord medicalRecord) {
            return ! medicalRecord.hasTakenBloodTestsLately();
        }
    },
    CCC(20) { // ... also implements the abstract method and so on

    private final int threshold;

    private BloodTest(int threshold) {
        this.threshold = threshold;
    }

    public boolean hasPassed(int value) {
        return value <= threshold;
    }

    public abstract boolean isRequired(MedicalRecord medicalRecord);

    // ... same as above
}

现在,一旦获得对某些BloodTest的引用,您可以通过调用相应的方法来检查是否通过了switch并且逻辑遍布客户端代码来传递特定的测试:

BloodTest bloodTest = BloodTest.valueOf(someString); // someString can be "AAA", "BBB" or "CCC"
// no matter which constant this is, you use it as an object and rely on polymorphism
if (bloodTest.hasPassed(someValue)) { // ... do something

Q2:你的问题有两种“问题”是我对你实际需要枚举的初步假设。如果你有可能需要动态处理你还不知道的血液测试,那么就不能使用枚举。

换句话说,如果您的代码没有任何switchif/else if块来处理每次验血,那么枚举对您的用例来说是一个非常糟糕的选择。

但是,如果确实如此,我建议重构代码以将逻辑包含在枚举本身中,如上例所示,而不是switch / if块;此外,如果您的switchdefault个案例(或您的if有最后else个阻止),这仍然可以在枚举本身中建模,例如添加DEFAULT常数作为后备。

答案 2 :(得分:0)

我的枚举类之一的简短摘录:

public enum TypesStructurelsE {
    SOURCE("SRC"),
    COLONNE("COL");

    private String code;

    TypesStructurelsE(final String code1) {
        code = code1;
    }


    /** @return String */
    public String getCode() {
        return code;
    }

    public void setCode(final String newCode) {
        code = newCode;
    }
}

。 。在其他班级

if(TypesStructurelsE.SOURCE.getCode().equal(testName[i])){ // can be "COL" or "SRC" 
//
;
}

......改变价值:

TypesStructurelsE.SOURCE.setCode("SOURCE_NEW");

因此,如果您的属性文件发生更改,您只需使用新的symbole(SRC - &gt; SOURCE)进行编译