【问题标题】:Proper way testing that String belongs to subset of constants (Java)测试字符串属于常量子集的正确方法(Java)
【发布时间】:2016-08-29 15:10:30
【问题描述】:

目标:

  • 表示从抽象类中定义的字符串创建的字符串子集
  • 测试输入字符串是否属于给定子集

初步解决方案:

让我们列出可能的事件。

/**
* List of events.
*/
public abstract class EventKeys {

     public static final String KEY_EVENT_1 = "EVENT_1";
     public static final String KEY_EVENT_2 = "EVENT_2";
     public static final String KEY_EVENT_3 = "EVENT_3";
     public static final String KEY_EVENT_4 = "EVENT_4";
     public static final String KEY_EVENT_5 = "EVENT_5";
     public static final String KEY_EVENT_6 = "EVENT_6";
     public static final String KEY_EVENT_7 = "EVENT_7";
     //etc ..
}

我想制作这些事件的子集,例如事件 1、3、5,并且仅对这些事件允许一些操作。目标是使方法 boolean isEventAllowed(String eventKey) 说明事件是否属于允许事件的子集。

真正天真的方法是:

/**
* Allow only events 1,3,5
*/
private isEventAllowed(String eventKey) {

    if(eventKey.equals(EventKeys1.KEY_EVENT_1)) {
        return true;
    } else if(eventKey.equals(EventKeys1.KEY_EVENT_3)) {
        return true;
    }  else if(eventKey.equals(EventKeys1.KEY_EVENT_3)) {
        return true; 
    } else {
        return false;
    }
}

我觉得这种方法不是很方便。我需要更好的方法来表示字符串的子集并提供输入字符串是否属于定义的子集的操作?

其他可能的解决方案:
作为其他选项,我正在考虑其他两个选项,但我仍然不确定它是否是这样做的好方法。 1)枚举 - 创建字符串枚举

  • 输入枚举:EventKeys1.KEY_EVENT_1, EventKeys1.KEY_EVENT_2, EventKeys1.KEY_EVENT_3
  • 测试 String keyEvent 是否属于定义的枚举?

2) 列出

  • 创建列表List<String> subset并放在那里 EventKeys1.KEY_EVENT_1、EventKeys1.KEY_EVENT_2、EventKeys1.KEY_EVENT_3
  • 测试String keyEvent是否属于列表子集


请在回答前阅读此内容

  • 给定类 EventKeys,无法更改,主要选项集
  • 我需要以某种方式表示子集
  • 我需要更好地实现方法 isAllowedEvent(String keyEvent) 的建议,如果输入字符串则返回 true 属于定义的子集

【问题讨论】:

  • 考虑使用java.util.Set(例如,java.util.HashSetjava.util.TreeSet、...)
  • @B.Kemmer 目前在代码中,稍后可能来自某些配置文件,无论如何都会以某种方式映射到 KeyEvent 抽象类。用例是在抽象类中的事件上完成了一些动作,我只需要对某些事件执行一些其他动作,并且需要以某种方式表示子集。根据 cmets 最合适的可能是 HashSet + contains(eventKey) 它清晰且易于定制,并且肯定比 if/else if 解决方案更好
  • @jameslarge 感谢提示 HashSet 可能是我想要的

标签: java string enums subset


【解决方案1】:

这样的事情怎么样?

    private boolean isEventAllowed(String eventKey) {
      return Arrays.asList(KEY_EVENT_1, KEY_EVENT_3, KEY_EVENT_5).contains(eventKey);
    }

按照 John Fergus 的评论,可以通过使用以下内容来提高可读性:

    private static List<String> SUBSET = Arrays.asList(KEY_EVENT_1, KEY_EVENT_3, KEY_EVENT_5);

    private boolean isEventAllowed(String eventKey) {
      return SUBSET.contains(eventKey);
    }

【讨论】:

  • OP - 您的“子集”的可配置性如何?您可以定义单个键,然后还将“子集”定义为数组,以便您可以对其执行 EventKeys.ASubSet.contains(eventKey)?
  • 我可能会使用 Set subset = new HashSet();对于子集而不是 Arrays.asList 但想法仍然相同。谢谢
【解决方案2】:

虽然持有允许值的 Set 通常是首选选项,但您应该注意原始代码的语法改进,因为它们的一般模式也适用于其他情况。

类似的声明

if(condition1)
    action;
else if(condition2)
    /* (same) */ action;
…

是多余的,可以替换为

if(condition1 || condition2)
    action;
…

类似

if(condition)
    return true;
else
    return false;

是多余的,可能(甚至应该)被替换为

return condition;

将两者放在一起,您的原始代码就变成了

private boolean isEventAllowed(String eventKey) {
    return eventKey.equals(EventKeys1.KEY_EVENT_1)
        || eventKey.equals(EventKeys1.KEY_EVENT_3)
        || eventKey.equals(EventKeys1.KEY_EVENT_5);
}

或者,您可以使用switch 语句:

private boolean isEventAllowed(String eventKey) {
    switch(eventKey) {
        case EventKeys1.KEY_EVENT_1:
        case EventKeys1.KEY_EVENT_3:
        case EventKeys1.KEY_EVENT_5:
            return true;
        default:
            return false;
    }
}

不是每个人都喜欢这种编码风格,但这更多是项目或公司政策的问题。在某些情况下,这样的switch 声明仍然是最干净的解决方案。与if 语句甚至Set 方法相比的一个优势是,如果您错误地两次命名同一个常量而不是预期的常量(典型的复制和粘贴错误),编译器会立即喊叫,就像您在第三个if 中所做的那样声明您使用KEY_EVENT_3 而不是预期的KEY_EVENT_5...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多