4

这些说明中的哪个在性能和内存使用方面更好:

if(val.equals(CONSTANT1) || val.equals(CONSTANT2) ..... || val.equals(CONSTANTn)) {

}

或者

if(Arrays.asList(CONSTANT1,CONSTANT2, ..... ,CONSTANTn).contains(val)) {

}
4

4 回答 4

2

理论上 #1 更快但无关紧要,因为 Arrays.asList 只创建一个对象 - 指定数组的列表视图(包装器),没有数组复制:

public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}

private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
    private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;

ArrayList(E[] array) {
        if (array==null)
            throw new NullPointerException();
    a = array;
}
于 2013-02-19T10:55:12.333 回答
2

一个更好的问题是如何更清楚地编写此代码(如果性能确实很重要,则更快)。答案将是一个switch语句(或者甚至可能是多态性,如果你想将你的常量转换为一个枚举)或一个查找数组。

但是如果你坚持比较你的两种方法,第一种会稍微快一些。要了解这一点,让我们看看第二种方法的含义:

  1. 使用常量创建一个新数组,将它们传递给 Arrays.asList 的 vararg 参数
  2. 创建一个包装该数组的新列表对象
  3. 遍历该数组,将每个元素与 equals 进行比较

第三步相当于你的第一种方法。

最后,值得注意的是,这样的操作可能需要不到一微秒的时间,因此除非您每秒调用此方法数百万次,否则任何方法都足够快。

于 2014-02-01T13:02:54.090 回答
1

由于您没有使用循环,我猜值的数量是如此之少,以至于实际上任何差异都无关紧要。

但是,话虽如此,如果要手动迭代并使用 equals() 与 asList() 和 contains() ......它仍然是相同的。

Arrays.asList() 返回一个列表的私有实现,它扩展了 AbstractList 并通过引用简单地环绕现有数组(不进行复制)。contains() 方法使用 indexOf() 对每个元素使用 equals() 遍历数组,直到找到匹配项然后返回它。如果你在找到一个等于时打破你的循环,那么这两个实现将是相当等价的。

唯一的区别是 Arrays.asList() 创建的附加列表结构的内存占用很小,除此之外......

于 2013-02-19T10:55:48.160 回答
0

if(val.equals(CONSTANT1) || val.equals(CONSTANT2) ..... || val.equals(CONSTANTn)) {

}

在性能和内存方面更好,因为第二个需要时间来构建一个列表并开始在该列表中搜索 val。这里需要额外的内存来维护列表,并且需要额外的时间来遍历列表。其中将 val 与常量进行比较将使用短路比较方法。

于 2013-02-19T10:48:45.300 回答