【问题标题】:Use static final unmodifiable Set as constant for checking variables value使用 static final unmodifiable Set 作为常量来检查变量值
【发布时间】:2012-12-11 12:32:06
【问题描述】:

我经常遇到一种验证模式,在这种模式下,为了有效,一些变量必须包含前缀数量的值之一。

PSEUDO CODE:
    IF x == CONSTANT_1 || X == CONSTANT_2 || ... || x == CONSTANT_N
    THEN X is valid

为了避免 OR 术语链,我创建了一个静态的最终不可修改集,其中包含所有常量:

public final static String CONSTANT_1 = *value* ;
public final static String CONSTANT_2 = *value* ;
...
public final static String CONSTANT_N = *value* ;

public final static Set SET_OF_CONSTANTS = Collections.unmodifiableSet(new HashSet(){
    private static final long serialVersionUID = 1L;
    {
        add(CONSTANT_1); 
        add(CONSTANT_2);
        ...
        add(CONSTANT_3);
    }
});

我通过以下方式执行检查:

if(!SET_OF_CONSTANTS.contains(x)){ 
    //X NOT VALID 
}

我想知道这是否是一种好的编程实践,是否有任何替代方法,以及使用哈希表查询(理论上为 O(1))而不是 OR 术语链是否可以提高性能也许还有代码可读性。

【问题讨论】:

  • 我觉得这个风格很好。就性能而言,在我根据典型数据分析应用程序之前,我不会尝试优化任何东西。
  • +1 表示 NPE。永远不要假设你的性能瓶颈在哪里,也永远不要过早地优化
  • 是的,这是真的。还有一个替代方案,EnumSet,它被实现为位集操作。虽然它可能无法用作就地替代品,但可能需要更改 API。
  • 注意: 将字符串与== 进行比较在大多数情况下都是错误的。在大多数情况下,您必须使用aString.equals(otherString)stackoverflow.com/questions/767372/java-string-equals-versus
  • 为什么不是哈希图,因为常量是键值对?

标签: java coding-style


【解决方案1】:

总的来说,我认为这是非常好的风格。

差别不大,但我个人会这样定义SET_OF_CONSTANTS

      public final static String CONSTANT_1 = "*value*";
      public final static String CONSTANT_2 = "*value*";
              ...
      public final static String CONSTANT_N = "*value*";

      public final static Set<String> SET_OF_CONSTANTS = Collections.unmodifiableSet(
        new HashSet<String>(Arrays.asList(
              CONSTANT_1, 
              CONSTANT_2,
                      ...
              CONSTANT_N
              )));

我不完全清楚您是否需要单独的 CONSTANT_1 常量,或者您是否可以简单地将值折叠到 SET_OF_CONSTANTS 中。

就性能而言,在我根据真实数据分析代码之前,我不会开始优化任何东西。

最后要注意,当x是一个字符串时,下面的可能是不正确的:

IF x == CONSTANT_1 || x == CONSTANT_2 || ... || x == CONSTANT_N

在这里,== 可能应该替换为对equals() 的调用。

【讨论】:

  • 感谢您的回答。无论如何,我知道 == 和 equals 之间有什么区别。我使用 == 的帖子的第一部分旨在用作伪代码而不是 Java 代码。抱歉,如果不清楚。我编辑了我的帖子。
  • (或者== 是对的,你应该使用Collections.newSetFromMap(new IdentityHashSet&lt;&gt;(...)),但这留下了... 的用途。我承认不太可能。)
【解决方案2】:

另一种(更短的)方法是使用 Set.of :

public final static Set SET_OF_CONSTANTS = Collections.unmodifiableSet(
    Set.of(CONSTANT_1, CONSTANT_2, CONSTANT_3));

【讨论】:

  • 自Java9以来的正确答案。
  • 需要 java 9。
猜你喜欢
  • 1970-01-01
  • 2011-05-23
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2015-12-27
  • 1970-01-01
  • 2019-09-02
  • 2015-05-11
相关资源
最近更新 更多