我有一个常量列表,想要检查传递给方法的值是否等于其中一个常量。我知道Enums会很好,但出于性能原因,我需要一个int值。枚举值可以有一个值,但我担心获取int值比直接使用int慢。
public static final int
a = Integer.parseInt("1"), // parseInt is necessary in my application
b = Integer.parseInt("2"),
c = Integer.parseInt("3");
public void doIt(int param) {
checkIfDefined(param);
...
}
问题是关于checkIfDefined
。我可以使用if
:
if(param == a)
return;
if(param == b)
return;
if(param == c)
return
throw new IllegalArgumentException("not defined");
或者我可以使用Arrays.binarySearch(int[] a, int key)
,或者......更好的主意?
也许枚举不仅在优雅方面而且在速度方面都会更好,因为我不需要运行时检查。
解决方案
由于enum
和switch
在parseInt
的特殊情况下是否有效,我现在使用普通的旧常量和Arrays.binarySearch
。
答案 0 :(得分:1)
我有理由相信,获取枚举的int
属性值与获取int值的常量一样快。 (但如果有疑问,为什么不制作原型并测量两种解决方案的性能?)使用enum
s使您的代码更具可读性,总是值得花费额外的努力。
对于快速查找,如果您只有无符号整数值,则可以将枚举值存储在ArrayList
中,并按其各自的int
值编制索引。
答案 1 :(得分:1)
您更喜欢使用枚举:
public enum Letters {
A("1"), B("2"), C("3");
private final String value;
private Letters(String value) {
this.value = value;
}
public Letters getByValue(String value) {
for (Letters letter : values()) {
if (letter.value.equals(value)) return letter;
}
throw new IllegalArgumentException("Letter #" + value + " doesn't exist");
}
public int toInt() {
return Integer.parseInt(value);
}
}
答案 2 :(得分:1)
如果您的常量列表很长,请将它们加载到HashSet
。这将为您提供最快的查找时间:所有对哈希映射的查找都是O(1)时间(除了整数的自动装箱之外,还有低常量成本)。
如果您的常量列表很短且不变,请使用switch语句并让编译器为您构建一个HashSet(没有自动装箱)。
如果介于两者之间,请将它们放入数组中,对其进行排序,然后使用Arrays.binarySearch
。您可以在设置一个整数所需的时间内进行大约5-10次比较,因此一旦数字达到数百,我就会切换到HashSet。
如果它很短,并且您知道哪个号码最有可能出现,请在if语句中手动编码,先检查最常见的号码。
答案 3 :(得分:0)
switch 声明怎么样?您可以在默认情况下抛出异常。
答案 4 :(得分:0)
我猜你发布的阵列解决方案只要params的数量很少就会禁食。如果它大于128并且你经常需要这个,那么我会使用HashSet:
Set<Integer> params = new HashSet<Integer>();
params.add(Integer.valueOf("1"));
params.add(Integer.valueOf("2"));
params.add(Integer.valueOf("3"));
public boolean checkIfDefined(int param){
return params.contains(param);
}
自动装箱肯定很慢,但是哈希查找O(1)而不是O(log n)作为二进制搜索。
2。)如果内存不是很重要或者参数没有达到很高的值,那么禁食解决方案是使用boms []将params作为索引:
boolean[] params = new boolean[MAX_PARAMS+1];
params[Integer.parseInt("1")] = true;
params[Integer.parseInt("2")] = true;
params[Integer.parseInt("3")] = true;
public boolean checkIfDefined(int param){
if (param < 0 || params.length <= param)
return false;
return params[param];
}