116

Basically my mate has been saying that I could make my code shorter by using a different way of checking if an int array contains an int, although he won't tell me what it is :P.

Current:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

Have also tried this, although it always returns false for some reason.

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

Could anyone help me out?

Thank you.

pbaris
  • 4,525
  • 5
  • 37
  • 61
Caleb
  • 1,484
  • 2
  • 12
  • 10
  • 8
    Your Arrays.asList(...) call takes a vararg, that is it will wrap the arbitrary number of arguments you might pass into that in a List. In your case, you're getting a list of arrays with a single element, and this list obviously does not contain the int. – sarcan Aug 18 '12 at 16:45
  • Your comment meaning what now? – sarcan Aug 18 '12 at 16:49
  • check `Hashset` based retrial mechanism answer. It is the fastest way. – Amit Deshpande Aug 18 '12 at 17:22
  • I don't see any point at making your original code shorter since your argument is a primitive array and your code is very clear and straightfoward. `ArrayList` implementation is doing the same. – Genzer Aug 18 '12 at 17:38
  • I would not make your code shorter. (1) arraylist does the same thing you did. (2) - more important stuff is that the shorten code using Arrays.asList creates new object, which could be problem within some performance critical code. The first code snippet is best thing you can do. – Martin Podval Jan 05 '15 at 06:33
  • The iterative solution is nice. Of course you can use a Hashtable to optimize the speed of the lookup, but that means to convert the initial array into a hashtable, which is also an iterative process. Anyway, I would add a "break" statement when the item is found, because when it is found, you don't need to iterate to the end of the array – Nicolas Dec 19 '15 at 03:54
  • Hi, even if the JDK8 version is smaller the speed depenends on the list size. For example if your list contain less than 10 elements the simple array loop could be much faster because integer call are fast an there is no calling overhead like in the jdk8 solution. For really large set you sould use an "Set<>" but it is only faster if you reuse it. – SkateScout Oct 18 '16 at 11:28
  • Your Current is the best way if your using Java 7, int, with no 3rd Party libraries. – Tim Boland Jun 09 '17 at 17:02

15 Answers15

77

You could simply use ArrayUtils.contains from Apache Commons Lang library.

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • 1
    As long as you are using ArrayUtils, is there any reason not to use [ArrayUtils.contains](https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/ArrayUtils.html#contains(int[],%20int)) – mejdev Dec 23 '14 at 17:52
  • 2
    No reason whatsoever :) – Reimeus Dec 23 '14 at 19:51
  • 32
    It's worth noting that `ArrayUtils.contains()` is part of `Apache Commons Lang` library. Even though that's a great lib, it is probably still not a good idea to add external dependency just to check if array contains an element :D – Krzysiek Mar 09 '17 at 20:33
  • 2
    ArrayUtils is a thing of past. Java 8+ and Guava have pretty amazing goodies!! – TriCore May 13 '17 at 23:41
69

Here is Java 8 solution

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}
TriCore
  • 1,844
  • 1
  • 16
  • 17
40

It's because Arrays.asList(array) returns List<int[]>. The array argument is treated as one value you want to wrap (you get a list of arrays of ints), not as vararg.

Note that it does work with object types (not primitives):

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

or even:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

But you cannot have List<int> and autoboxing is not working here.

dan1st
  • 12,568
  • 8
  • 34
  • 67
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
21

A different way:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

This modifies the passed-in array. You would have the option to copy the array and work on the original array i.e. int[] sorted = array.clone();
But this is just an example of short code. The runtime is O(NlogN) while your way is O(N)

Martin Marconcini
  • 26,875
  • 19
  • 106
  • 144
Cratylus
  • 52,998
  • 69
  • 209
  • 339
  • 36
    I think I'd be surprised if a `contains` method modified my array. – Zong Aug 18 '12 at 16:56
  • @ZongLi:This is just an example for the OP.Updated OP if we are nitpicking – Cratylus Aug 18 '12 at 17:01
  • 5
    From javadoc of binarySearch(): "the return value will be >= 0 if and only if the key is found." so Arrays.binarySearch(array,key)>=0 should be returned! – icza Apr 24 '14 at 12:25
  • Supplement: The return value of binarySearch() is (-(insertion point) - 1) if key is not contained which may likely be a value other than -1. – icza Apr 24 '14 at 12:32
  • This can't be `-1` if it is intending to be true. "The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size() if all elements in the list are less than the specified key.". Need to say `>= 0`. – Engineer2021 Apr 25 '14 at 13:14
  • 1
    Sorting and binary-searching is more "expensive" than full scan. (Besides the fact that array would be modified) – TriCore Jun 04 '17 at 05:01
21

Guava offers additional methods for primitive types. Among them a contains method which takes the same arguments as yours.

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

You might as well statically import the guava version.

See Guava Primitives Explained

Evert
  • 319
  • 2
  • 3
19

I know it's super late, but try Integer[] instead of int[].

Willy Wonka
  • 459
  • 5
  • 12
3

1.one-off uses

List<T> list=Arrays.asList(...)
list.contains(...)

2.use HashSet for performance consideration if you use more than once.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)
JaskeyLam
  • 15,405
  • 21
  • 114
  • 149
2

You can convert your primitive int array into an arraylist of Integers using below Java 8 code,

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

And then use contains() method to check if the list contains a particular element,

boolean containsElement = arrayElementsList.contains(key);
Hetal Rachh
  • 1,393
  • 1
  • 17
  • 23
1

You can use java.util.Arrays class to transform the array T[?] in a List<T> object with methods like contains:

Arrays.asList(int[] array).contains(int key);
IgniteCoders
  • 4,834
  • 3
  • 44
  • 62
1

Java 9+

public boolean contains(final int[] array, final int key) {
    return List.of(array).contains(key);
}
Mahmoud
  • 9,729
  • 1
  • 36
  • 47
0

this worked in java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}
  • It should immediately return on first match, instead this will still scan all the items in array, even if it did find the match. (Consider an array of trilion items) – TriCore May 13 '17 at 23:49
  • You are right try this public static boolean contains(final int[] array, final int key) { return Arrays.stream(array).anyMatch(n->n==key); } – Farhad Baghirov May 15 '17 at 05:38
  • Java 8 stream anyMatch is a [short-circuit operation](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#anyMatch-java.util.function.Predicate-) and will not scan all items in the array. – LordParsley Apr 25 '18 at 14:11
  • @LordParsley Above code's goal is check element in array ,not scan all element of array. – Farhad Baghirov Apr 27 '18 at 05:34
  • Sorry, I see the answer was edited. I was just reiterating it was correct as it will not need to scan all if it finds one part way. – LordParsley Apr 28 '18 at 13:24
0

Try this:

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}
Mosius
  • 1,602
  • 23
  • 32
0
private static void solutions() {
    int[] A = { 1, 5, 10, 20, 40, 80 };
    int[] B = { 6, 7, 20, 80, 100 };
    int[] C = { 3, 4, 15, 20, 30, 70, 80, 120 };

    List<Integer> aList = Arrays.stream(A).boxed().collect(Collectors.toList());

    List<Integer> cList = Arrays.stream(C).boxed().collect(Collectors.toList());
    String s = "";
    for (Integer a : C) {
        if (aList.contains(a) && cList.contains(a)) {
            s = s.concat(String.valueOf(a)).concat("->");
        }
    }
}
Kunal
  • 51
  • 1
-1

Depending on how large your array of int will be, you will get much better performance if you use collections and .contains rather than iterating over the array one element at a time:

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}
-6

Try Integer.parseInt() to do this.....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75