Home How can I test if an array contains a certain value?
Reply: 24

How can I test if an array contains a certain value?

Mike Sickler
1#
Mike Sickler Published in 2009-07-15 00:03:21Z

I have a String[] with values like so:

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?

camickr
2#
camickr Reply to 2016-04-09 23:39:25Z
Arrays.asList(yourArray).contains(yourValue)

Warning: this doesn't work for arrays of primitives (see the comments).


Since java-8

You can now use a Stream to check whether an array of int, double or long contains a value (by respectively using a IntStream, DoubleStream or LongStream)

Example

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
GKFX
3#
GKFX Reply to 2017-06-23 19:08:04Z

You can use the Arrays class to 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.

Uri
4#
Uri Reply to 2014-07-14 15:13:06Z

If the array is not sorted, you will have to iterate over everything and make a call to equals on each.

If the array is sorted, you can do a binary search, there's one in the Arrays class.

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.

Craig P. Motlin
5#
Craig P. Motlin Reply to 2013-10-09 22:42:04Z

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. It should be private:

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

(Note, you can actually drop the new String[]; bit.)

So, reference arrays are bad, and in particular here 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 even be made public.)

"Given String s, is there a good way of testing whether VALUES contains s?"

VALUES.contains(s)

O(1).

Tom Hawtin - tackline
6#
Tom Hawtin - tackline Reply to 2009-07-15 01:18:26Z

ObStupidAnswer (but I think there's a lesson in here somewhere):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
camickr
7#
camickr Reply to 2009-07-15 01:34:20Z

For what its 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().

When using a 10K array size the results where:

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

When using a 100K array the results where:

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.

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));
    }
}
MetroidFan2002
8#
MetroidFan2002 Reply to 2013-12-02 16:36:25Z

Actually , if you use HashSet 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.

It all depends on how your code is set up, obviously, but from where I stand, the order would be:

On an UNsorted array:

  1. HashSet
  2. asList
  3. sort & Binary

On a sorted array:

  1. HashSet
  2. Binary
  3. asList

So either way, HashSet ftw

Mark Rhodes
9#
Mark Rhodes Reply to 2012-10-05 07:48:46Z

Instead of using the quick array initialsation syntax to you could just initialise it as a List straight away in a similar manner using the Arrays.asList method e.g.:

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

Intracer
10#
Intracer Reply to 2015-10-19 20:49:40Z

You can use ArrayUtils.contains from Apache Commons Lang

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

Note that this method returns false if the passed array is 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.
}
jhodges
11#
jhodges Reply to 2012-09-19 14:13:40Z

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)

This really removes a lot of clutter from the initialization proposed

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
icza
12#
icza Reply to 2014-11-14 19:56:42Z

I'm surprised no one suggested to just simply implement it by hand:

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:

The v != null condition is constant inside the method, it always evaluates to the same boolean value during the method call. So if the input array is big, it is more efficient to evaluate this condition only once and we can use a simplified/faster condition inside the for loop based on the result. The improved contains() method:

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;
}
Community
13#
Community Reply to 2017-05-23 12:18:30Z
  1. For arrays of limited length use the following (as given by camickr). This is slow for repeated checks, especially for longer arrays (linear search).

     Arrays.asList(...).contains(...)
    
  2. For fast performance if you repeatedly check against a larger set of elements

    • An array is the wrong structure. Use a TreeSet and add each element to it. It sorts elements and has a fast exist() method (binary search).

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

      ElementClass.compareTo() method must be compatable with ElementClass.equals(): see 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);
      
Rob
14#
Rob Reply to 2013-05-30 07:18:55Z

Use Array.BinarySearch(array,obj) for finding the given object in array or not. Ex:

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

false --not exists

Pang
15#
Pang Reply to 2018-01-08 03:27:44Z

Try this:

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");
}
assylias
16#
assylias Reply to 2014-03-13 15:02:36Z

With Java 8 you can create a stream and check if any entries in the stream matches "s":

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

Or as a generic method:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}
Ryan
17#
Ryan Reply to 2014-04-07 19:53:57Z

Using a simple loop is the most efficient way of doing this.

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

Courtesy to Programcreek

GurV
18#
GurV Reply to 2017-12-04 02:00:36Z

Four Different Ways to Check If an Array Contains a Value

1) Using List:

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

2) Using Set:

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

3) Using a simple loop:

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

4) Using Arrays.binarySearch():

The code below is wrong, it is listed here for completeness. binarySearch() can ONLY be used on sorted arrays. You will find the result is weird below. This is the best option when array is sorted.

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

Quick Example:

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
Pang
19#
Pang Reply to 2018-01-08 03:26:35Z

Check this

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
    }
}
Nepster
20#
Nepster Reply to 2014-06-25 07:24:12Z

Developers often do:

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

The above code works, but there is no need to convert a list to set first. Converting a list to a set requires extra time. It can as simple as:

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

or

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

return false;

The first one is more readable than the second one.

Abhishek Oza
21#
Abhishek Oza Reply to 2014-07-23 13:25:35Z

I am very late to join this discussion, but since my approach in solving this problem, when I faced it a few years ago, was a bit different than the other answers already posted here, I am posting that solution I used at that time, over here, in case anyone finds it usefull: (The contains() method is ArrayUtils.in() in this code.)

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

}

As you can see in the code above, that there are other utility methods ObjectUtils.equals() and ArrayUtils.indexOf(), that were used at other places as well.

Pang
22#
Pang Reply to 2018-01-08 03:29:05Z

One possible solution:

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");
      }
  }
}
Shineed Basheer
23#
Shineed Basheer Reply to 2015-04-28 06:40:26Z

In Java 8 use 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);
WIll
24#
WIll Reply to 2017-10-02 02:54:25Z

Arrays.asList => then applying the contains() method will always work, but a search algorithm is much better since first, you have to convert the Array to a list, then calling the contains method, double the overhead, see what I mean? This is because it is O(n) to create the List and O(n) to for contains to find an element through sequential checking. Why suffer O(n) twice when a simple linear search does the job only once.

public boolean findString(String[] strings, String desired){
   for(String s : strings){
       if (desired.equals(s)){
           return true;
       }
   }
   return false; //if we get hereā€¦ there is no desired String, return false.
}
Stephen Rauch
25#
Stephen Rauch Reply to 2017-09-27 04:14:20Z

It can be as simple as:

String[] VALUE = new String[] {"AB","BC","CD","AE"};
Arrays.asList(VALUE).contains(s);
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.360494 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO