如何确定数组是否包含 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:04:05  来源:igfitidea点击:

How do I determine whether an array contains a particular value in Java?

javaarrays

提问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 VALUEScontains 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, doubleor longcontains a value use IntStream, DoubleStreamor LongStreamrespectively.

要检查int,double或的数组是否long包含值IntStream,请分别使用,DoubleStreamLongStream

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().containswould 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:

未排序的数组上:

  1. HashSet
  2. asList
  3. sort & binary
  1. 哈希集
  2. 列表
  3. 排序和二进制

On a sorted array:

在排序数组上:

  1. HashSet
  2. Binary
  3. asList
  1. 哈希集
  2. 二进制
  3. 列表

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.containsfrom Apache Commons Lang

您可以ArrayUtils.containsApache Commons Lang 使用

public static boolean contains(Object[] array, Object objectToFind)

public static boolean contains(Object[] array, Object objectToFind)

Note that this method returns falseif 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");