您认为哪种效率更高?
使用'WeekDay'只是一个例子:
public enum WeekDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
}
Run Code Online (Sandbox Code Playgroud)
循环并首先验证日期字符串:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; // day 'should' always be a weekday
if (isValidWeekDay(day)) {
WeekDay weekDay = WeekDay.valueOf(day); // won't throw exception
...
} else {
throw new InvalidWeekDayException(day); // subclass of RuntimeException
}
}
private boolean isValidWeekDay(String day) {
for (WeekDay weekDay : WeekDay.values()) {
if(weekDay.toString().equals(day))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
或者因为在99.99%的情况下,一天是正确的:
public void parseString(String line) {
String[] tokens = line.split();
String day = tokens[1]; // day 'should' always be a weekday
try {
WeekDay weekDay = WeekDay.valueOf(day); // might throw exception
...
} catch (IllegalArgumentException e) {
throw new InvalidWeekDayException(day, e);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
为了澄清,输入字符串将来自客户端应用程序,而不是用户.换句话说,在这个例子中收到非工作日会是一个错误.
第二种方法的性能问题是什么?抓住这样的例外几乎没有任何成本.从设计角度来看,使用异常进行正常控制流通常是一个坏主意,这是性能考虑的日子早已不复存在.在调试器中,使用异常作为重要的控制操作会使事情减慢大约10倍.但这会被JIT优化,并且在生产中没有可测量的影响.
这些数字是基于我对zxing项目进行评估的经验,该项目使用了各种流量控制的例外情况.当我第一次看到它时,我感到震惊.我仍然认为这不是最好的设计,但我做了相当多的测试,可以肯定地说它对性能没有实际影响.这是一种在整个地方使用异常进行流量控制的算法.您的情况,即异常只会在非常特殊的情况下被抛出,这是一个非问题.
编辑:我的回答中有一两个问题,我想确保我对我所说的内容非常清楚:我不认为对正常控制流使用异常是个好主意.仅仅因为性能不是不使用异常的好方法,这并不意味着没有其他完全正确的原因(例如可读性,可测试性,可扩展性).在OP的情况下,绝对要求使用异常,并且肯定不会导致任何类型的性能问题.
正如已经评论过的那样,您必须进行剖析才能确定.即使在您自己的解析方法中,您也可以通过在解析列表时返回枚举来加快速度.
private WeekDay getValidWeekDay(String day) {
for (WeekDay weekDay : WeekDay.values()) {
if(weekDay.toString().equals(day))
return weekDay;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
除非这是一个时间关键的应用程序,否则我不会在任何一种情况下担心它,只需采用最易读的方法.我认为这将使用WeekDay.valueOf()方法.
如果您不想处理异常,那么在枚举中创建一个值的Map,并从查找中有效地执行valueOf(),如果找不到则返回null.
public enum WeekDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
private static Map<String, WeekDay> valueMap;
public static WeekDay getValue(String possibleName)
{
if (valueMap == null)
{
valueMap = new HashMap<String, WeekDay>();
for(WeedDay day: values())
valueMap.put(day.toString(), day);
}
return valueMap.get(possibleName);
}
}
Run Code Online (Sandbox Code Playgroud)
这实际上是valueOf()方法正在做的事情,除非它在找不到时抛出IllegalArgumentException.这种方法只会返回null,因此不会生成堆栈跟踪.
小智 6
我知道这是一个老帖子,但我相信以下结果仍然很有趣.我运行10000000个测试来查找enum ENUM {FIRST, SECOND, THIRD, FOURTH, LAST}
使用JDK 1.8 的元素.下表显示了简单循环所需的时间valueOf()
.
text loop valueOf ratio ------------------------------ "FIRST" 121 65 186% "LAST" 188 57 330% "foo" 155 8958 1.7%
结论 - valueOf()
如果我希望值与枚举不匹配,我就不会使用.