【问题标题】:Fetch all string value pair from Constant.java File从 Constant.java 文件中获取所有字符串值对
【发布时间】:2014-08-29 03:19:10
【问题描述】:

我有一个现有的Constant.java,我必须使用它编写一个逻辑,以便如果输入字符串包含任何常量字符串,然后执行一些操作。

 public class Constants {

    public static final String CONSTANT_ONE = "VALUE_CONSTANT_ONE";
    public static final String CONSTANT_TWO = "VALUE_CONSTANT_TWO";
    //and so on..
}

Validate.checkPhrase() 是一个布尔方法,它接受输入字符串和常量字符串作为参数,将它们转换为小写并将输出传递给java.lang.String.contains() 方法进行验证。

在我的主要逻辑中,我使用 if 有多个条件

if (Validate.checkPhrase(str,CONSTANT_ONE) 
|| Validate.checkPhrase(str,CONSTANT_TWO)|| /* multiple checks */ ){
//do something
}

每次添加新常量时,我​​也必须手动将其添加到if condition。 有没有办法可以从Constant.java 获取所有字符串、值对并在我的逻辑中使用它。

【问题讨论】:

  • 使用枚举,使用循环并迭代其值,调用 checkPhrase 并返回 true 并在成功验证时中断,否则继续验证。如果没有一个迭代验证成功,则返回 false。
  • 如果您发现自己不断地添加常量(明白了吗?),您可能不想将它们放在一个类中(这意味着重新编译、重新部署等),而是放在一个配置文件中。这样您就可以轻松地修改常量列表,并且只需要重新加载您的应用程序。
  • 另外,根据您的 Java 版本,您可以在字符串上使用 switch

标签: java string if-statement constants


【解决方案1】:

我认为没有更好的方法来做到这一点。

我建议您开始寻找 Constants 课程的替代品。

最明显的方法是将类替换为enum 类型。这将允许您执行以下操作:

  • 遍历枚举的所有值,

  • switch-ing 枚举值,或

  • 定义谓词以对枚举值进行子分类。

另一种方法是将所有常量字符串放入一个数组 ... 或者如果某种类型的 Set ... 并遍历数组或在集合上使用 contains。 (请注意,迭代大量字符串效率不高...)

如果您需要动态的常量字符串集,那么您可以摆脱 命名 常量和静态初始化的数组/集合。将它们替换为 Map<String, Int> 并从配置文件或数据库或类似的东西中填充它。 (这将不允许您使用 Java 标识符来引用源代码中的常量...)


请注意,enum 类型在 Java 中已支持多年。我原以为你的 Constants应该早就被替换了......

【讨论】:

  • 他必须在引入新的枚举值时添加一个新的 switch case。
  • @Shail016 - 这是真的。但他将不得不修改使用常量的代码......无论如何。
【解决方案2】:

您可以尝试以下类似的方法:

enum CONSTANTS {
    VALUE_CONSTANT_ONE, VALUE_CONSTANT_TWO
}

然后像这样使用它:

        boolean result = false;
       //simulates your if ( checkPhrase ||checkPhrase)
        for (CONSTANTS c : CONSTANTS.values()) {
            result = Validate.checkPhrase(str,c.toString());
            if (result) {
                break;
            }
        }
        if (result) {
            System.out.println("do your stuff");
        }

这样,如果你添加一个新的枚举,检查仍然不受影响。

如果不想再次编译,请使用属性文件,例如constants.properties

CONSTANT_ONE=VALUE_CONSTANT_ONE
CONSTANT_TWO=VALUE_CONSTANT_TWO

并且可以像下面这样使用它:

    Properties constants = new Properties();
    try (FileInputStream fin = new FileInputStream(
            "D:\\constants.properties");) {
        constants.load(fin);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // to check whats loaded
    System.out.println(constants);
    String str = "Your String";
    boolean result = false;
    for (String key : constants.stringPropertyNames()) {
        result = Validate.checkPhrase(str, constants.getProperty(key));
        if (result) {
            break;
        }
    }
    if (result) {
        System.out.println("do your stuff");
    }

【讨论】:

  • 这里我每次更新Constant.java文件时都必须更新enum?如果我错了,请纠正我,我之前没有使用过enum
  • 是的,如果你想要一个新的常量,你需要把它放在你的枚举中并重新构建你的代码。如果经常更改,将常量放在属性/配置文件中是更好的选择,因为那时不需要编译。要知道枚举参考:docs.oracle.com/javase/tutorial/java/javaOO/enum.html
  • 还可以考虑Properties 类,您可以将文件中的键值对加载到其中,然后您可以遍历这些值并执行所需的检查。参考:docs.oracle.com/javase/7/docs/api/java/util/Properties.html
【解决方案3】:

要获取所有常量,您可以使用以下代码 -

    HashMap<String,String> pairs= new HashMap<String,String>();
    Constants constants= new Constants();
    Field[] f = constants.getClass().getFields();
    for (int i = 0; i < f.length; i++) {
        pairs.put(f[i].getName().toLowerCase(),f[i].get(constants).toString());
    }
    System.out.println(pairs);

更新 -

由于所有字段都是静态的,我们可以使用类名访问它 -

    HashMap<String,String> pairs= new HashMap<String,String>();
    for(Field field :Constants.class.getFields())
    { 
        pairs.put(field.getName().toLowerCase(),field.get(null).toString());
    }
    System.out.println(pairs);

地图输出 -

{constant_two=VALUE_CONSTANT_TWO, constant_one=VALUE_CONSTANT_ONE}

【讨论】:

  • 事实上,如果所有字段都是静态的,则无需创建类常量的实例。以下也应该有效。 for(Field field :Constants.class.getFields()){ System.out.println(field.getName()+ " "+ field.get(null)); }
  • 我想说的是下面的代码应该可以工作: HashMap pairs= new HashMap(); for(Field field :Constants.class.getFields()) { pairs.put(field.getName().toLowerCase(),field.get(null).toString()); } System.out.println(pairs);
【解决方案4】:

正如您所认识到的,通常应该避免使用 if else-if 块,因为它们会使代码难以阅读并添加不需要的依赖项。

在这种情况下,为什么不把你所有的常量放在一个列表或其他类型的容器中呢?然后您可以使用

遍历列表

Validate.CheckPhrase(str, list[index])

【讨论】:

    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    相关资源
    最近更新 更多