如何确定数组是否包含 Java 中的特定值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1128723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I determine whether an array contains a particular value in Java?
提问by Mike Sickler
I have a String[]
with values like so:
我有一个String[]
像这样的值:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Given String s
, is there a good way of testing whether VALUES
contains s
?
鉴于String s
,是否有一种测试是否VALUES
包含的好方法s
?
采纳答案by camickr
Arrays.asList(yourArray).contains(yourValue)
Warning: this doesn't work for arrays of primitives (see the comments).
警告:这不适用于基元数组(请参阅注释)。
Since java-8you can now use Streams.
从java-8 开始,您现在可以使用 Streams。
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
To check whether an array of int
, double
or long
contains a value use IntStream
, DoubleStream
or LongStream
respectively.
要检查int
,double
或的数组是否long
包含值IntStream
,请分别使用,DoubleStream
或LongStream
。
Example
例子
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
回答by Thomas Owens
You can use the Arrays classto perform a binary search for the value. If your array is not sorted, you will have to use the sort functions in the same class to sort the array, then search through it.
您可以使用Arrays 类对值执行二进制搜索。如果您的数组未排序,则必须使用同一类中的排序函数对数组进行排序,然后搜索它。
回答by Uri
If the array is not sorted, you will have to iterate over everything and make a call to equals on each.
如果数组未排序,则必须遍历所有内容并在每个内容上调用 equals。
If the array is sorted, you can do a binary search, there's one in the Arraysclass.
如果数组已排序,则可以进行二进制搜索,Arrays类中有一个。
Generally speaking, if you are going to do a lot of membership checks, you may want to store everything in a Set, not in an array.
一般来说,如果您要进行大量成员资格检查,您可能希望将所有内容存储在一个 Set 中,而不是一个数组中。
回答by Tom Hawtin - tackline
Concise update for Java SE 9
Java SE 9 的简明更新
Reference arrays are bad. For this case we are after a set. Since Java SE 9 we have Set.of
.
引用数组不好。对于这种情况,我们需要一组。从 Java SE 9 开始,我们有Set.of
.
private static final Set<String> VALUES = Set.of(
"AB","BC","CD","AE"
);
"Given String s, is there a good way of testing whether VALUES contains s?"
“给定 String s,是否有一种测试 VALUES 是否包含 s 的好方法?”
VALUES.contains(s)
O(1).
O(1)。
The right type, immutable, O(1)and concise. Beautiful.*
的权利类型,不可变的,O(1)和简洁。美丽的。*
Original answer details
原答案详情
Just to clear the code up to start with. We have (corrected):
只是为了清除代码开始。我们有(更正):
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
This is a mutable static which FindBugs will tell you is very naughty. Do not modify statics and do not allow other code to do so also. At an absolute minimum, the field should be private:
这是一个可变的静态,FindBugs 会告诉你它非常顽皮。不要修改静态,也不允许其他代码这样做。至少,该字段应该是私有的:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
(Note, you can actually drop the new String[];
bit.)
(请注意,您实际上可以删除该new String[];
位。)
Reference arrays are still bad and we want a set:
引用数组仍然不好,我们想要一个集合:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
(Paranoid people, such as myself, may feel more at ease if this was wrapped in Collections.unmodifiableSet
- it could then even be made public.)
(偏执狂的人,比如我,如果把Collections.unmodifiableSet
它包起来可能会更放心——然后它甚至可以公开。)
(*To be a little more on brand, the collections API is predictably still missing immutable collection types and the syntax is still far too verbose, for my tastes.)
(*为了更多地了解品牌,可以预见的是,集合 API 仍然缺少不可变的集合类型,而且语法对于我的口味来说仍然过于冗长。)
回答by Tom Hawtin - tackline
ObStupidAnswer (but I think there's a lesson in here somewhere):
ObStupidAnswer(但我认为这里有一个教训):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
回答by camickr
For what it's worth I ran a test comparing the 3 suggestions for speed. I generated random integers, converted them to a String and added them to an array. I then searched for the highest possible number/string, which would be a worst case scenario for the asList().contains()
.
值得一提的是,我进行了一项测试,比较了 3 条速度建议。我生成了随机整数,将它们转换为字符串并将它们添加到数组中。然后我搜索了可能的最高数字/字符串,这对于asList().contains()
.
When using a 10K array size the results were:
使用 10K 数组大小时,结果为:
Sort & Search : 15 Binary Search : 0 asList.contains : 0
When using a 100K array the results were:
使用 100K 数组时,结果为:
Sort & Search : 156 Binary Search : 0 asList.contains : 32
So if the array is created in sorted order the binary search is the fastest, otherwise the asList().contains
would be the way to go. If you have many searches, then it may be worthwhile to sort the array so you can use the binary search. It all depends on your application.
所以如果数组是按排序顺序创建的,二分查找是最快的,否则asList().contains
就是要走的路。如果您有很多搜索,那么对数组进行排序可能是值得的,以便您可以使用二分搜索。这一切都取决于您的应用程序。
I would think those are the results most people would expect. Here is the test code:
我认为这是大多数人所期望的结果。下面是测试代码:
import java.util.*;
public class Test
{
public static void main(String args[])
{
long start = 0;
int size = 100000;
String[] strings = new String[size];
Random random = new Random();
for (int i = 0; i < size; i++)
strings[i] = "" + random.nextInt( size );
start = System.currentTimeMillis();
Arrays.sort(strings);
System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
System.out.println("Search : " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
System.out.println("Contains : " + (System.currentTimeMillis() - start));
}
}
回答by not
Actually, if you use HashSet<String> as Tom Hawtin proposed you don't need to worry about sorting, and your speed is the same as with binary search on a presorted array, probably even faster.
实际上,如果您像 Tom Hawtin 建议的那样使用 HashSet<String> ,则无需担心排序,并且您的速度与对预排序数组进行二分搜索的速度相同,甚至可能更快。
It all depends on how your code is set up, obviously, but from where I stand, the order would be:
显然,这完全取决于您的代码的设置方式,但从我的立场来看,顺序是:
On an unsortedarray:
在未排序的数组上:
- HashSet
- asList
- sort & binary
- 哈希集
- 列表
- 排序和二进制
On a sorted array:
在排序数组上:
- HashSet
- Binary
- asList
- 哈希集
- 二进制
- 列表
So either way, HashSet for the win.
所以无论哪种方式,HashSet 都是赢家。
回答by Mark Rhodes
Instead of using the quick array initialisation syntax too, you could just initialise it as a List straight away in a similar manner using the Arrays.asList method, e.g.:
您可以使用 Arrays.asList 方法以类似的方式直接将其初始化为 List,而不是使用快速数组初始化语法,例如:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
Then you can do (like above):
然后你可以做(如上):
STRINGS.contains("the string you want to find");
回答by Intracer
You can use ArrayUtils.contains
from Apache Commons Lang
您可以ArrayUtils.contains
从Apache Commons Lang 使用
public static boolean contains(Object[] array, Object objectToFind)
public static boolean contains(Object[] array, Object objectToFind)
Note that this method returns false
if the passed array is null
.
请注意,false
如果传递的数组是,则此方法返回null
。
There are also methods available for primitive arrays of all kinds.
还有一些方法可用于各种原始数组。
Example:
例子:
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
回答by jhodges
If you have the google collections library, Tom's answer can be simplified a lot by using ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)
如果你有谷歌收藏库,汤姆的答案可以通过使用 ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html) 简化很多
This really removes a lot of clutter from the initialization proposed
这确实从建议的初始化中消除了很多混乱
private static final Set<String> VALUES = ImmutableSet.of("AB","BC","CD","AE");