首页 文章

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

提问于
浏览
1966

我有 String[] 的值如下:

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

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

25 回答

  • 319

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

    如果数组已排序,您可以进行二进制搜索,Arrays类中有一个 .

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

  • 5

    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);
    
  • 3

    您可以使用 ArrayUtils.contains 来自Apache Commons Lang

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

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

    还有适用于各种原始数组的方法 .

    示例:

    String[] fieldsToInclude = { "id", "name", "location" };
    
    if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
        // Do some stuff.
    }
    
  • 4

    开发人员经常这样做:

    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;
    

    第一个比第二个更可读 .

  • 46

    一种可能的方案:

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

    为了它的 Value ,我进行了一项测试,比较了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));
        }
    }
    
  • 2

    检查一下

    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
        }
    }
    
  • 1

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

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

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

  • 65

    我很惊讶没有人建议只是简单地手工实现它:

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

    Improvement:

    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;
    }
    
  • 178

    使用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);
    }
    
  • 6

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

  • 1

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

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

    假 - 不存在

  • 15
    • 对于有限长度的数组,请使用以下内容(由 camickr 给出) . 这对于重复检查来说很慢,特别是对于较长的阵列(线性搜索) .
    Arrays.asList(...).contains(...)
    
    • 如果反复检查更多元素,则可获得快速性能

    • 数组是错误的结构 . 使用 TreeSet 并向其添加每个元素 . 它对元素进行排序并具有快速 exist() 方法(二进制搜索) .

    • If the elements implement Comparable & you want the TreeSet sorted accordingly:

    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));
    
    • Otherwise, use your own 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);
    
    • The payoff: check existence of some element:
    // Fast binary search through sorted elements (performance ~ log(size)):
    boolean containsElement = myElements.exists(someElement);
    
  • 2

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

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

    那么你可以做(如上): STRINGS.contains("the string you want to find");

  • 29

    只是为了开始清除代码 . 我们已经(更正):

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

    (偏执狂的人,比如我自己,如果被包裹在_67366中,可能会感到更放心 - 它甚至可以公之于众 . )

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

    VALUES.contains(s)
    

    O(1) .

  • 1

    如果你有google集合库,可以使用ImmutableSet简化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");
    
  • 61

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

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

    礼貌Programcreek

  • 9
    Arrays.asList(yourArray).contains(yourValue)
    

    警告:这不适用于基元数组(参见评论) .


    从java-8开始,您现在可以使用Streams .

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

    要检查 intdoublelong 数组是否包含值,请分别使用 IntStreamDoubleStreamLongStream .

    示例

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

    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.
    }
    
  • 2541

    实际上,如果您使用HashSet,Tom Hawtin建议您不必担心排序,并且您的速度与预分类阵列上的二进制搜索相同,可能更快 .

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

    在UNsorted数组上:

    • HashSet

    • asList

    • sort&Binary

    在排序的数组上:

    • HashSet

    • 二进制

    • asList

    无论哪种方式,HashSet ftw

  • 24

    我很晚才加入这个讨论,但是由于我在解决这个问题的方法,几年前我遇到它时,与我在这里发布的其他答案有点不同,我发布了我当时使用的解决方案,在这里,如果有人发现它有用:(在此代码中 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() ,它们也在其他地方使用过 .

  • 11

    ObStupidAnswer(但我觉得这里有一个教训):

    enum Values {
        AB, BC, CD, AE
    }
    
    try {
        Values.valueOf(s);
        return true;
    } catch (IllegalArgumentException exc) {
        return false;
    }
    
  • 30

    试试这个:

    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");
    }
    
  • 1

    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
    

相关问题