确定一个值是不是在 Java 中的一组值中的最快方法是啥?

Posted

技术标签:

【中文标题】确定一个值是不是在 Java 中的一组值中的最快方法是啥?【英文标题】:What is the fastest way to determine if a value is in a set of values in Java?确定一个值是否在 Java 中的一组值中的最快方法是什么? 【发布时间】:2012-02-17 21:50:28 【问题描述】:

对于各位 JAVA 专家来说,这可能是一个简单的问题,但我比较新,所以我想我会问。我需要测试字符串 X 是否存在于集合中。我不需要任何关联的值或索引,也不需要任何顺序。我只需要知道它是否存在。我知道这可以使用 HashMap 或 ArrayList 来实现,但这些似乎有点过头了。该怎么办?只是一个列表?或者有没有更基本的东西可以达到同样的目的。测试给定集合中是否存在某个字符串 X 的最快方法是什么?

【问题讨论】:

套装有多大?如果不使用真实数据进行基准测试,您将无法确定最快的解决方案。 【参考方案1】:

听起来你想要HashSet<String>

Set<String> set = new HashSet<String>();
set.add("foo");
set.add("bar");

boolean no = set.contains("baz");
boolean yes = set.contains("foo");

当然,还有其他可用的Set 实现,但HashSet 可能是这里最合适的。

【讨论】:

我们实际上使用了几乎相同的字符串名称 ;)【参考方案2】:

您不仅有ArrayListHashMap,JDK 附带了各种各样的类,您还可以在其中找到您要查找的内容:集合。

其中一个例如是HashSet,它具有您正在寻找的功能..

Set<String> set = new HashSet<String>();

set.add("foo");
set.add("bar");

boolean b = set.contains("foo");

【讨论】:

【参考方案3】:
import java.util.Arrays;

...

if (Arrays.asList("foo", "bar", "baz").contains(myString)) 
    ...

【讨论】:

这不会是有效的,因为与HashSet(常数 O(1) )或 TreeSet (我猜 O(logn) 如果我没记错) @Jack 对于非常小的集合(例如, 你说的都是对的——但是 OP 需要用适当大小的集合进行基准测试!【参考方案4】:

我知道这可以使用 HashMap 或 ArrayList 来实现,但这些似乎有点过头了。

使用一个设计的内建类来做你想做的事,而且做得非常快,到底是什么“矫枉过正”?因为这就是HashMapHashSet 在其接口(不是映射值)中会更基本一些,但它实际上是通过具有空值的 HashMap 来实现的。

【讨论】:

好吧,HashMap 旨在将键映射到值,这比 OP 想要的更多(因为他只需要“存在”)。 HashSet,另一方面...【参考方案5】:

有几个答案建议HashSet,其他人指出对于小集合来说更简单的集合可能更快——你还没有说集合的大小。

字符串的大小也是相关的,因为HashSet 等会使用字符串的哈希码,它是根据字符串的全部内容计算出来的(然后被缓存)。这可能需要一些时间 - 但另一方面,它可能已经计算过了,具体取决于您的代码,因此不会产生额外费用。

在某些情况下,您可以通过字符串的大小或通过检查前几个字符从集合中排除字符串 - 这取决于您的数据和字符串集合。 Trie 之类的数据结构在这里可能很有用 - (但您​​需要一个简单的解决方案)。

如果性能至关重要,那么您需要在现实条件下仔细地对所有建议的解决方案进行基准测试。见How do I write a correct micro-benchmark in Java?

如果您真的需要一个快速的解决方案(这对您的应用程序真的很重要吗?)那么您可能需要容忍“矫枉过正”!

【讨论】:

【参考方案6】:

不要使用包含使用Collections.binarySearch(List, Object)

使用此方法前别忘了排序Collections.sort(List)

【讨论】:

以上是关于确定一个值是不是在 Java 中的一组值中的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何从给定的一组值中进行选择,四舍五入?

如何确保一列包含一组值中的一个?

仅从一组值中检索给定标识符和一个列值的多个条目中的行

从具有相同 id 的一组值中选择最大值

调整 SVR 的超参数 [关闭]

将字符串重新分配给数组中的一组值列表