【问题标题】:using enums or static string variable in java在java中使用枚举或静态字符串变量
【发布时间】:2011-09-29 01:32:40
【问题描述】:

有一个关于哪个更好用的问题。 Java5 枚举或静态字符串。

我总是以字符串的形式获取数据。

例如,

private static final String LOAD_DRUGS = "load drug";

或使用 Java5 枚举

public enum LoadType
{
LOAD_DRUGS("load drugs");
}

在我的代码中,我总是收到“装载药物”之类的字符串。我使用 if else 语句来查看下一步该做什么。但我倾向于使用 java5 枚举并使用 switch case,但我总是必须根据我得到的字符串值来获取枚举。

那么这两种方式的优缺点是什么?

谢谢!!

【问题讨论】:

标签: java


【解决方案1】:

这个答案可能有点矫枉过正。也许有一个徽章。无论如何,它在您有很多枚举值并且必须处理字符串作为另一个系统向您发送信息的方式的情况下可能很有用。这正是我所拥有的(50 以北的东西),所以我使用了这个构造,以便我可以只生成一次由 db 报告的字符串和我在内部使用的枚举的映射,然后不再考虑它—— toString 和 fromString 完成所有工作:

package com.stevej;

import com.google.common.collect.HashBiMap;

public enum TestEnum {
  ALPHA("Alpha"), BETA("Beta"), GAMMA("Gamma");

  private static HashBiMap<TestEnum, String> stringMapping = HashBiMap
      .create(TestEnum.values().length);

  private String stringValue = null;

  TestEnum(String stringValue) {
    this.stringValue = stringValue;
  }

  String getStringValue() {
    return this.stringValue;
  }

  @Override
  public String toString() {
    return stringMapping.get(this);
  }

  public static TestEnum fromString(String string) {
    return stringMapping.inverse().get(string);
  }

  static {
    for (TestEnum e : TestEnum.values()) {
      stringMapping.put(e, e.getStringValue());
    }
  }
}

这是一个显示数据来回切换的快速测试:

package com.stevej;

public class StackOverflowMain {

  public static void main(String[] args) {
    System.out.println(">> " + TestEnum.ALPHA);
    System.out.println(">> " + TestEnum.BETA);
    System.out.println(">> " + TestEnum.GAMMA);

    TestEnum a = TestEnum.fromString("Alpha");
    TestEnum b = TestEnum.fromString("Beta");
    TestEnum c = TestEnum.fromString("Gamma");

    System.out.println(">> " + a);
    System.out.println(">> " + b);
    System.out.println(">> " + c);
  }

}

输出显示使用混合大小写的值而不是大写,显示正在使用我的字符串:

>> 阿尔法
>> 测试版
>> 伽玛
>> 阿尔法
>> 测试版
>> 伽玛

请注意,我使用的是 Google Guava 库,因此我可以利用 BiMap。

【讨论】:

  • 我看到 JohnB 提出了一些类似的建议。
  • 由于Map 只在一个方向上导航,一个简单、标准的HashMap 也可以做得很好。
  • 映射在静态方法fromString()中反向使用。 BiMap 还强制执行字符串必须与枚举值一样唯一的规则。
  • 抱歉不够清楚:由于映射仅用于一个方向 - 反向 - 您可以使用简单的 HashMap&lt;String,TestEnum&gt; 并在静态初始化器中构造该反向映射。实际上不允许重复的字符串。并且由于编译器将检查TestEnum 端是否存在重复,因此这对于 BiMap 也没有意义。除了这个小点之外,这是我看到许多 enum 定义并为我自己创建它们的方式。
  • 但我使用前向映射进行 toString 操作。也许我错过了一些东西。本质上,我想在两个方向上覆盖 StringEnum。我的枚举值的字符串表示是唯一出现的。
【解决方案2】:

你可以尝试一个简单的替换把字符串变成一个枚举

switch(MyEnum.valueOf(text.replace(' ', '_')) {
    case load_strings:

如果你想要大写,你可以使用 toUpperCase()。

你应该做你认为最简单、最清楚的事情。

【讨论】:

  • @claymore1977,我同意。我并不是说这是一个好主意,但你可以做到。 ;)
  • 我不是在问如何从字符串转换为枚举。只是想知道使用这些方法的优缺点是什么。谢谢!!
  • @Rishi,在这种情况下,我会说这在您的示例中并不重要。如果您打算使用 enum 作为对象而不是字符串列表,这会产生更大的不同。
  • 我看到的问题是维护和灵活性问题。从维护的角度来看,这个 text.replace() 将不得不出现在所有地方。如果模式发生变化,那么需要修复很多代码。它假设相同的模式适用于每个枚举。这可能不够灵活。我想要一个将枚举值与任意字符串匹配的解决方案,唯一的限制是字符串在枚举值中必须是唯一的。这样我就可以将传递字符串的服务与解释它们的代码分离。
  • @Steve J,那么您将如何在不添加方法调用的情况下处理字符串中的空格?
【解决方案3】:

通常您应该使用枚举来存储一组以某种方式相关的值。它们都应该具有类似的“是”关系。它不应该用于简单地存储一组不相关的常量字符串。

当然,如果您对一组字符串值有一个 switch 语句,那么这表明这些字符串值是相关的并且应该被分组为一个 Enum 并使用 enum 的机制来使用 switch。

如果传递的字符串等于名称值,则枚举类型的 valueOf 方法将允许您从 String 转换为枚举类型。如果不是这种情况,您可以实现自己的 valueOf,它使用存储的字符串字段而不是名称。您可以将字段存储在私有静态地图中以进行转换。

【讨论】:

    【解决方案4】:

    因为枚举是键入的。

    没有输入静态字符串。

    public enum Something{
      CAT("cat");
    
      private String animal;
    
      private Something(String animal){
        this.animal = animal;
      }
    
      public String getAnimal(){
        return this.animal;
      }
    }
    

    【讨论】:

    • 从类型安全的角度来看,使用 switch/case 的枚举可以确保比使用 if/else 的字符串更高的性能。我知道 if/else 和 switch/case 在性能上是如何考虑的,但在这种情况下看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    相关资源
    最近更新 更多