代码之家  ›  专栏  ›  技术社区  ›  Mike Sickler

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

  •  2030
  • Mike Sickler  · 技术社区  · 15 年前

    我有一个 String[] 值如下:

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

    鉴于 String s 有没有好的方法来测试 VALUES 包含 s ?

    25 回复  |  直到 6 年前
        1
  •  2621
  •   Ray Hulha    6 年前
    Arrays.asList(yourArray).contains(yourValue)
    

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


    自从 现在可以使用流。

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

    检查 int , double long 包含值使用 IntStream , DoubleStream LongStream 分别。

    例子

    int[] a = {1,2,3,4};
    boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
    
        2
  •  325
  •   Craig P. Motlin    11 年前

    先清除代码。我们已经(更正):

    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,是否有一种测试值是否包含s的好方法?”

    VALUES.contains(s)
    

    O(1)。

        3
  •  185
  •   Intracer    9 年前

    你可以使用 ArrayUtils.contains Apache Commons Lang

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

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

    还有一些方法可用于各种基元数组。

    例子:

    String[] fieldsToInclude = { "id", "name", "location" };
    
    if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
        // Do some stuff.
    }
    
        4
  •  148
  •   Peter Mortensen icecrime    6 年前

    只需手动执行即可:

    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;
    }
    
        5
  •  66
  •   Uri    10 年前

    如果数组未排序,则必须遍历所有内容,并对每个内容调用equals。

    如果对数组进行排序,则可以执行二进制搜索,其中 Arrays 班级。

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

        6
  •  63
  •   Gurwinder Singh    7 年前

    Four Different Ways to Check If an Array Contains a Value

    1)使用列表:

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

    2)使用集合:

    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)使用array.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
    
        7
  •  47
  •   camickr    15 年前

    为了它的价值,我做了一个测试,比较了3个速度建议。我生成随机整数,将其转换为字符串并将其添加到数组中。然后我搜索尽可能多的数字/字符串,这对于aslist().contains()来说是最坏的情况。

    当使用10 k数组大小时,结果如下:

    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));
        }
    }
    
        8
  •  33
  •   assylias    11 年前

    使用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);
    }
    
        9
  •  31
  •   Peter Mortensen icecrime    6 年前

    您可以使用array.as list方法直接将其初始化为列表,而不是使用快速数组初始化语法,例如:

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

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

    STRINGS.contains("the string you want to find");
    
        10
  •  25
  •   GKFX    7 年前

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

        11
  •  16
  •   Tom Hawtin - tackline    15 年前

    顽固分子(但我认为在这里有个教训):

    enum Values {
        AB, BC, CD, AE
    }
    
    try {
        Values.valueOf(s);
        return true;
    } catch (IllegalArgumentException exc) {
        return false;
    }
    
        12
  •  12
  •   Peter Mortensen icecrime    6 年前

    实际上,如果您按照Tom Hawtin的建议使用hashset<string>,则无需担心排序问题,而且您的速度与预排序数组上的二进制搜索速度相同,甚至可能更快。

    显然,这完全取决于代码的设置方式,但从我的立场来看,顺序是:

    关于一个 未分类的 数组:

    1. 哈希表
    2. 阿斯利特
    3. 排序和二进制

    在已排序的数组上:

    1. 哈希表
    2. 二元的
    3. 阿斯利特

    所以不管怎样,都是为了胜利。

        13
  •  10
  •   jhodges    12 年前

    如果你有google收藏库,Tom的答案可以通过使用不可变集(http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/immutableset.html)简化很多。

    这确实从提议的初始化中消除了很多混乱。

    private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
    
        14
  •  9
  •   Pang Ajmal PraveeN    7 年前

    一种可能的解决方案:

    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");
          }
      }
    }
    
        15
  •  7
  •   Zar E Ahmer    10 年前

    开发人员经常这样做:

    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;
    

    第一个比第二个更可读。

        16
  •  6
  •   Shineed Basheer    10 年前

    爪哇8 使用流。

    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);
    
        17
  •  5
  •   Ryan    11 年前

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

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

    礼貌对待 Programcreek

        18
  •  4
  •   Community CDub    8 年前
    1. 对于有限长度的数组,使用以下内容(如 卡米克 )重复检查的速度很慢,特别是对于较长的数组(线性搜索)。

       Arrays.asList(...).contains(...)
      
    2. 如果您重复检查一组较大的元素,则可以获得快速性能

      • 数组的结构不正确。使用A TreeSet 并将每个元素添加到其中。它对元素进行排序并具有快速的 exist() 方法(二进制搜索)。

      • 如果元素实现 Comparable &您需要 有序树 相应排序:

        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);
        
        19
  •  3
  •   Pang Ajmal PraveeN    7 年前

    试试这个:

    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");
    }
    
        20
  •  3
  •   Peter Mortensen icecrime    6 年前

    使用以下 contains() 方法是 ArrayUtils.in() 在本代码中):

    对象实用程序.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);
        }
    
    }
    

    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() 在其他地方也使用过。

        21
  •  2
  •   Pang Ajmal PraveeN    7 年前

    检查这个

    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
        }
    }
    
        22
  •  2
  •   TheArchon    6 年前

    arrays.aslist()->然后调用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
  •  2
  •   Akhil Babu Korkandi    6 年前

    如果你不想让它区分大小写

    Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
    
        24
  •  2
  •   Ruslan    6 年前

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

    例子:

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

    假--不存在

        25
  •  -2
  •   mandy1339    7 年前

    创建一个最初设置为假的布尔值。运行一个循环来检查数组中的每个值,并与要检查的值进行比较。如果有匹配,请将Boolean设置为true并停止循环。然后断言布尔值为真。