如何检查参数值是否在常量列表中

时间:2010-02-22 14:31:16

标签: java performance list enums

我有一个常量列表,想要检查传递给方法的值是否等于其中一个常量。我知道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),或者......更好的主意?

也许枚举不仅在优雅方面而且在速度方面都会更好,因为我不需要运行时检查。

解决方案

由于enumswitchparseInt的特殊情况下是否有效,我现在使用普通的旧常量和Arrays.binarySearch

5 个答案:

答案 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];
}