Categories
arrays java

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

2576

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?

7

  • 6

    Long way around it, but you can use a for loop: “for (String s : VALUES) if (s.equals(“MYVALUE”)) return true;

    – Zack

    Jul 15, 2009 at 0:51

  • 3

    @camickr–I have a nearly identical situation with this one: stackoverflow.com/a/223929/12943 It just keeps getting votes yet was just a copy/paste from sun’s documentation. I guess score is based on how much help you provided and not how much effort you put into it–and mostly how fast you post it! Maybe we’ve stumbled onto John Skeet’s secret! Well good answer, +1 for you.

    – Bill K

    Apr 29, 2013 at 6:50


  • 2

    If you’re using Apache Commons, then org.apache.commons.lang.ArrayUtils.contains() does this for you.

    – Mr. Boy

    Nov 12, 2013 at 21:05

  • 43

    @camickr because people, like me, google a question, click on the SO result, see your answer, test it, it works, upvote the answer and then leave.

    – Aequitas

    Jul 20, 2015 at 2:41

  • 2

    I really miss a simple indexOf and contains in java.util.Arrays – which would both contain straightforward loops. Yes, you can write those in 1 minute; but I still went over to StackOverflow expecting to find them somewhere in the JDK.

    – tucuxi

    May 1, 2020 at 10:38

3252

Arrays.asList(yourArray).contains(yourValue)

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


Since you can now use Streams.

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

To check whether an array of int, double or long contains a value use IntStream, DoubleStream or LongStream respectively.

Example

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

33

  • 106

    I am somewhat curious as to the performance of this versus the searching functions in the Arrays class versus iterating over an array and using an equals() function or == for primitives.

    Jul 15, 2009 at 0:06

  • 195

    You don’t lose much, as asList() returns an ArrayList which has an array at its heart. The constructor will just change a reference so that’s not much work to be done there. And contains()/indexOf() will iterate and use equals(). For primitives you should be better off coding it yourself, though. For Strings or other classes, the difference will not be noticeable.

    – Joey

    Jul 15, 2009 at 0:09

  • 19

    Odd, NetBeans claims that ‘Arrays.asList(holidays)’ for an ‘int[] holidays’ returns a ‘list<int[]>’, and not a ‘list<int>’. It just contains one single element. Meaning the Contains doesn’t work since it just has one element; the int array.

    – Nyerguds

    Nov 13, 2010 at 13:15


  • 65

    Nyerguds: indeed, this does not work for primitives. In java primitive types can’t be generic. asList is declared as <T> List<T> asList(T…). When you pass an int[] into it, the compiler infers T=int[] because it can’t infer T=int, because primitives can’t be generic.

    Jun 14, 2011 at 16:51


  • 29

    @Joey just a side note, it’s an ArrayList, but not java.util.ArrayList as you expect, the real class returned is: java.util.Arrays.ArrayList<E> defined as: public class java.util.Arrays {private static class ArrayList<E> ... {}}.

    Oct 17, 2012 at 9:16

415

Concise update for Java SE 9

Reference arrays are bad. For this case we are after a set. Since Java SE 9 we have 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?”

VALUES.contains(s)

O(1).

The right type, immutable, O(1) and concise. Beautiful.*

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:

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

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

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.)

(*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.)

13

  • 197

    Except it’s O(N) to create the collection in the first place 🙂

    Apr 25, 2011 at 6:54

  • 67

    If it’s static, it’s probably going to be used quite a few times. So, the time consumed to initialise the set has good chances of being quite small compared to the cost of a lot of linear searches.

    – Xr.

    Oct 12, 2011 at 19:39

  • 2

    @TomHawtin-tackline Why do you say “in particular here we want a set”? What is the advantage of a Set (HashSet) in this case? Why is a “reference array” bad (by “reference array” do you mean an ArrayList backed by an array as generated by a call to Arrays.asList)?

    Aug 29, 2014 at 5:04


  • 7

    @nmr A TreeSet would be O(log n). HashSets are scaled such that the mean number of elements in a bucket is roughly constant. At least for arrays up to 2^30. There may be affects from, say, hardware caches which the big-O analysis ignores. Also assumes the hash function is working effectively.

    Sep 9, 2014 at 23:51


  • 3

    This doesn’t answer the question about the array. You just say “don’t use arrays” which is not a solution. Additionally, you just say “X is bad” but don’t explain why which is always bad for an answer.

    – Minn

    Aug 18, 2019 at 20:37

232

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

8

  • 4

    @max4ever I agree, but this is still better then “rolling your own” and easier to read then the raw java way.

    – Jason

    Dec 7, 2012 at 17:48

  • 2

    package: org.apache.commons.lang.ArrayUtils

    – slamborne

    Jan 31, 2014 at 2:39


  • 45

    @max4ever Sometimes you already have this library included (for other reasons) and it is a perfectly valid answer. I was looking for this and I already depend on Apache Commons Lang. Thanks for this answer.

    – GuiSim

    Apr 22, 2014 at 19:30

  • 1

    Or you could just copy the method (and depedencies if there are any).

    – Buffalo

    Mar 9, 2015 at 11:59

  • 11

    @max4ever Most android apps are minimalized by Proguard, putting only the classes and functions you need into your app. That makes it equal to roll your own, or copy the source of the apache thing. And whoever doesn’t use that minimalization doesn’t need to complain about 700kb or 78kb 🙂

    Aug 12, 2016 at 13:11