【发布时间】:2016-01-18 11:34:43
【问题描述】:
所以,我经常遇到这个成语:
import java.util.HashSet;
import java.util.Set;
public class Test {
private static final Set<String> VALUES = new HashSet<String>();
static {
VALUES.add("good");
VALUES.add("bad");
VALUES.add("ugly");
}
public static void main(String[] args) {
if (VALUES.contains(args[0])) {
System.out.println("Thumbs up for Sergio Leone!");
} else {
System.out.println("Whatever.");
}
}
}
产生一个布尔输出,判断输入值(很可能是字符串)是否匹配任何固定值集合(最可能是字符串常量或字符串字面量)。
我看到了几个不同的实现,例如:
带有或运算符的布尔表达式。
一个值数组 + 一个 foreach 循环遍历匹配的值。
前一个的变体:一个值数组,为 Arrays.binarySearch() 排序。
使用 ArrayList 或 HashSet + contains() 等集合,见上文。
我觉得这里缺乏一个通用的、最佳的实现,因为我经常遇到这种成语。尽管如此,所有上述实现都感觉像是临时解决方案。我想知道是否:
a) 标准 Java 集合框架已经为此类任务提供了解决方案。
b) 如果没有,是否已经有合适的第三方实现(例如一些 Apache Commons 库)。
要求(按重要性排序):
最适合几十个元素(相对于复杂的数据结构,例如为快速访问数百万条目而设计的哈希表/树)。
快速实例化,占用内存小。
没有隐晦的第三方依赖,最好建立在纯 Java 之上。
此外,在我的情况下,JRE 1.6 合规性是必须的,尽管我也对基于较新 Java 版本构建的解决方案感到好奇。 (这意味着向我指出基于 JRE 1.8 的解决方案可能会获得支持,但不会获得答案标记,抱歉。)
初始化(实例化?)完成后,它应该是不可变的——我们只需要将它用于类似 contains() 的检查。
如果我们尝试在初始化时冗余地添加值,应该抛出异常。
【问题讨论】:
-
“最有可能”是什么意思? HashSet 有什么问题?
-
您是否会动态地实例化它们,或者像上面的示例中给出的那样一直使用相同的值静态地实例化它们?如果是后者,那么您可以使用
enum -
@Sleiman Jneidi 最有可能的意思是,它应该针对小尺寸而不是数百万个元素进行优化。这意味着如果有人决定将它用于它不适合的用途,它仍然可以处理数百万个元素,只是与已建立的集合(如 HashSet、TreeSet 等)相比,基于性能考虑,这将是一个糟糕的决定。 ,请参阅 Arrays 中的排序实现,在选择方法时通常会考虑数组长度。
-
@Kevin Esche 按规则进行静态实例化。使用枚举(+ 枚举字段,如有必要)可能是一种解决方案,是的。
-
@Sleiman Jneidi 我确实一直在使用 HashSet :-) 我只是想知道是否有另一种解决方案,也许是更高效和/或更易读和/或更优雅的解决方案。因此问题。
标签: java collections