如何确定数组是否包含Java中的特定值?

时间:2009-07-15 00:03:22

标签: java arrays

我有一个String[],其价值如下:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

鉴于String s,是否有一种测试VALUES是否包含s的好方法?

30 个答案:

答案 0 :(得分:2710)

Arrays.asList(yourArray).contains(yourValue)

警告:这不适用于基元数组(请参阅注释)。


开始,您现在可以使用Streams。

String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);

要检查intdoublelong数组是否包含值,请分别使用IntStreamDoubleStreamLongStream。< / p>

实施例

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);

答案 1 :(得分:334)

只需清除代码即可。我们已经(更正):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

这是一个可变的静态,FindBugs会告诉你这是非常顽皮的。它应该是私人的:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(注意,您实际上可以删除new String[];位。)

因此,参考数组很糟糕,特别是在这里我们需要一个集合:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(像我这样的偏执狂人,如果将其包含在Collections.unmodifiableSet中,可能会感到更放心 - 甚至可以将其公之于众。)

“给定字符串s,是否有一种测试VALUES是否包含s的好方法?”

VALUES.contains(s)

O(1)。

更新:自Java SE 9起,我们有Set.of

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

正确类型不可变 O(1)简洁。美丽。

(为了更多关于品牌,收藏API可以预见仍然缺少不可变的集合类型,而且根据我的口味,语法仍然过于冗长。)

答案 2 :(得分:188)

您可以使用Apache Commons Lang

中的ArrayUtils.contains

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

请注意,如果传递的数组为false,则此方法返回null

还有各种原始数组可用的方法。

实施例

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}

答案 3 :(得分:151)

只需简单地手工实施:

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

<强>改进:

v != null条件在方法内是常量。它始终在方法调用期间计算为相同的布尔值。因此,如果输入array很大,则仅评估此条件一次更有效,并且我们可以基于结果在for循环内使用简化/更快的条件。改进的contains()方法:

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } 
    else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}

答案 4 :(得分:68)

如果数组未排序,则必须迭代所有内容并在每个数组上调用equals。

如果数组已排序,您可以进行二分查找,Arrays类中有一个。

一般来说,如果要进行大量的成员资格检查,您可能希望将所有内容存储在Set中,而不是存储在数组中。

答案 5 :(得分:66)

Four Different Ways to Check If an Array Contains a Value

1)使用List:

public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
}

2)使用Set:

public static boolean useSet(String[] arr, String targetValue) {
    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);
}

3)使用简单的循环:

public static boolean useLoop(String[] arr, String targetValue) {
    for (String s: arr) {
        if (s.equals(targetValue))
            return true;
    }
    return false;
}

4)使用Arrays.binarySearch():

以下代码有误,此处列出的是完整性。 binarySearch()只能用于排序数组。你会发现下面的结果很奇怪。这是排序数组时的最佳选择。

public static boolean binarySearch(String[] arr, String targetValue) {  
            int a = Arrays.binarySearch(arr, targetValue);
            return a > 0;
        }

快速示例:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false

答案 6 :(得分:48)

为了什么值得,我进行了一项测试,比较了3个速度建议。我生成了随机整数,将它们转换为String并将它们添加到数组中。然后我搜索了最高可能的数字/字符串,这对于asList().contains()来说是最糟糕的情况。

使用10K阵列大小时,结果如下:

Sort & Search   : 15
Binary Search   : 0
asList.contains : 0

使用100K阵列时,结果如下:

Sort & Search   : 156
Binary Search   : 0
asList.contains : 32

因此,如果数组是按排序顺序创建的,则二进制搜索是最快的,否则asList().contains将是最佳选择。如果您有很多搜索,那么对数组进行排序可能是值得的,这样您就可以使用二进制搜索。这一切都取决于您的应用程序。

我认为这些是大多数人所期望的结果。这是测试代码:

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));
    }
}

答案 7 :(得分:34)

使用Java 8,您可以创建一个流并检查流中的任何条目是否与"s"匹配:

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

或者作为通用方法:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}

答案 8 :(得分:33)

您也可以使用Arrays.asList方法以类似的方式直接将其初始化为List,而不是使用快速数组初始化语法,例如:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

然后你可以做(​​如上所述):

STRINGS.contains("the string you want to find");

答案 9 :(得分:26)

您可以使用Arrays class对值执行二进制搜索。如果您的数组未排序,则必须使用同一类中的排序函数对数组进行排序,然后搜索它。

答案 10 :(得分:18)

ObStupidAnswer(但我认为这里有一个教训):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}

答案 11 :(得分:13)

实际上,如果你使用HashSet&lt; String&gt;正如Tom Hawtin建议您不必担心排序,并且您的速度与预先排序的数组上的二进制搜索相同,可能更快。

这一切都取决于您的代码的设置方式,显然,但从我的立场来看,订单将是:

未排序的数组上:

  1. HashSet的
  2. asList
  3. sort&amp;二进制
  4. 在排序数组上:

    1. HashSet的
    2. 二进制
    3. asList
    4. 无论哪种方式,胜利的HashSet。

答案 12 :(得分:11)

如果你有google集合库,可以使用ImmutableSet(http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet)简化Tom的答案。 HTML)

这确实从建议的初始化

中消除了很多混乱
private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");

答案 13 :(得分:10)

一种可能的解决方案:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}

答案 14 :(得分:8)

开发人员经常这样做:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

上面的代码有效,但不需要先将列表转换为set。将列表转换为集合需要额外的时间。它可以很简单:

Arrays.asList(arr).contains(targetValue);

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

第一个比第二个更可读。

答案 15 :(得分:7)

Java 8 中使用Streams。

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);

答案 16 :(得分:7)

使用简单的循环是最有效的方法。

boolean useLoop(String[] arr, String targetValue) {
    for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }
    return false;
}

礼貌Programcreek

答案 17 :(得分:5)

  1. 对于有限长度的数组,请使用以下内容(由 camickr 指定)。重复检查的速度很慢,尤其是对于较长的阵列(线性搜索)。

     Arrays.asList(...).contains(...)
    
  2. 如果您反复检查更多元素

    ,以获得快速性能
    • 数组是错误的结构。使用 TreeSet 并将每个元素添加到其中。它对元素进行排序,并具有快速exist()方法(二进制搜索)。

    • 如果元素实现Comparable&amp;您希望TreeSet相应地排序:

      ElementClass.compareTo()方法必须与ElementClass.equals()兼容:请参阅Triads not showing up to fight? (Java Set missing an item)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
      
    • 否则,请使用您自己的Comparator

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
    • 收益:检查是否存在某个元素:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);
      

答案 18 :(得分:4)

试试这个:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}

答案 19 :(得分:4)

使用以下内容(此代码中的contains()方法为ArrayUtils.in()):

ObjectUtils.java

public class ObjectUtils{

    /**
     * A null safe method to detect if two objects are equal.
     * @param object1
     * @param object2
     * @return true if either both objects are null, or equal, else returns false.
     */
    public static boolean equals(Object object1, Object object2){
        return object1==null ? object2==null : object1.equals(object2);
    }

}

ArrayUtils.java

public class ArrayUtils{

    /**
     * Find the index of of an object is in given array, starting from given inclusive index.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @param start  The index from where the search must start.
     * @return Index of the given object in the array if it is there, else -1.
     */
    public static <T> int indexOf(final T[] ts, final T t, int start){
        for(int i = start; i < ts.length; ++i)
            if(ObjectUtils.equals(ts[i], t))
                return i;
        return -1;
    }

    /**
     * Find the index of of an object is in given array, starting from 0;
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  indexOf(ts, t, 0)
     */
    public static <T> int indexOf(final T[] ts, final T t){
        return indexOf(ts, t, 0);
    }

    /**
     * Detect if the given object is in the given array.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  If indexOf(ts, t) is greater than -1.
     */
    public static <T> boolean in(final T[] ts, final T t){
        return indexOf(ts, t) > -1 ;
    }

}

正如您在上面的代码中所看到的,还有其他实用方法ObjectUtils.equals()ArrayUtils.indexOf(),它们也在其他地方使用过。

答案 20 :(得分:3)

检查

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}

答案 21 :(得分:3)

使用Array.BinarySearch(array,obj)查找数组中的给定对象。

示例:

if (Array.BinarySearch(str, i) > -1)` → true --exists

false - 不存在

答案 22 :(得分:3)

Arrays.asList() - &gt;然后调用contains()方法将始终有效,但搜索算法要好得多,因为您不需要在数组周围创建一个轻量级的列表包装器,这就是Arrays.asList()所做的。

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}

答案 23 :(得分:3)

如果您不希望它区分大小写

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);

答案 24 :(得分:2)

最短的解决方案
数组 VALUES 可能包含重复项
从 Java 9 开始

List.of(VALUES).contains(s);

答案 25 :(得分:1)

尝试使用Java 8谓词测试方法

这里是一个完整的例子。

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
 public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");

 public static void main(String args[]) {
  Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
  for (String i : VALUES) {

   System.out.println(containsLetterA.test(i));
  } 
 }
}

http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html

https://github.com/VipulGulhane1/java8/blob/master/Test.java

答案 26 :(得分:1)

当我使用基本类型byte和byte []处理低级Java时,到目前为止,我得到的最好的结果是 bytes-java https://github.com/patrickfav/bytes-java似乎是一件很不错的工作

答案 27 :(得分:0)

创建一个最初设置为false的布尔值。运行循环以检查数组中的每个值,并与要检查的值进行比较。如果你得到一个匹配项,将boolean设置为true并停止循环。然后断言布尔值为真。

答案 28 :(得分:0)

使用 Spliterator 防止不必要的生成 List

boolean found = false;  // class variable

String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );

found == true(如果数组中包含search


用于基元数组

public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false;  // class variable

int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
…

答案 29 :(得分:-2)

您可以通过两种方法进行检查

A)通过将数组转换为字符串,然后通过.contains方法检查所需的字符串

 String a=Arrays.toString(VALUES);
    System.out.println(a.contains("AB"));
    System.out.println(a.contains("BC"));
    System.out.println(a.contains("CD"));
    System.out.println(a.contains("AE"));

B)这是一种更有效的方法

 Scanner s=new Scanner(System.in);


   String u=s.next();
   boolean d=true;
    for(int i=0;i<VAL.length;i++)
    {
        if(VAL[i].equals(u)==d)
            System.out.println(VAL[i] +" "+u+VAL[i].equals(u));  

    }