Java, Simplified check if int array contains int
Asked Answered
E

15

117

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.

Elutriate answered 18/8, 2012 at 16:41 Comment(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.Bedrabble
Your comment meaning what now?Bedrabble
check Hashset based retrial mechanism answer. It is the fastest way.Chronology
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.Protagoras
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.Benfield
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 arrayCorri
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.Greenman
Your Current is the best way if your using Java 7, int, with no 3rd Party libraries.Proteus
C
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.

Colorblind answered 18/8, 2012 at 16:45 Comment(1)
Why autoboxing does not work, is it because it is declared as final?Morava
U
80

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);
}
Unrighteous answered 18/8, 2012 at 16:50 Comment(4)
As long as you are using ArrayUtils, is there any reason not to use ArrayUtils.containsDemarco
No reason whatsoever :)Unrighteous
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 :DPragmatics
ArrayUtils is a thing of past. Java 8+ and Guava have pretty amazing goodies!!Iridic
I
71

Here is Java 8 solution

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}
Iridic answered 31/12, 2015 at 5:52 Comment(1)
Note that this call requires API level 24Agnusago
C
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.

Colorblind answered 18/8, 2012 at 16:45 Comment(1)
Why autoboxing does not work, is it because it is declared as final?Morava
M
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)

Makkah answered 18/8, 2012 at 16:50 Comment(6)
I think I'd be surprised if a contains method modified my array.Glans
@ZongLi:This is just an example for the OP.Updated OP if we are nitpickingMakkah
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!Dugong
Supplement: The return value of binarySearch() is (-(insertion point) - 1) if key is not contained which may likely be a value other than -1.Dugong
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.Attainable
Sorting and binary-searching is more "expensive" than full scan. (Besides the fact that array would be modified)Iridic
P
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

Proportionate answered 16/7, 2013 at 16:39 Comment(0)
B
19

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

Bertilla answered 16/12, 2014 at 13:13 Comment(0)
C
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(...)
Chesterton answered 22/8, 2014 at 8:54 Comment(0)
R
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);
Reconstruct answered 26/5, 2019 at 13:15 Comment(0)
V
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);
Valentinavalentine answered 20/11, 2014 at 4:14 Comment(0)
H
1

Java 9+

public boolean contains(final int[] array, final int key) {
    return List.of(array).contains(key);
}
Hairdresser answered 19/11, 2021 at 1:48 Comment(0)
G
0

this worked in java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}
Griffiths answered 29/10, 2016 at 19:44 Comment(5)
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)Iridic
You are right try this public static boolean contains(final int[] array, final int key) { return Arrays.stream(array).anyMatch(n->n==key); }Griffiths
Java 8 stream anyMatch is a short-circuit operation and will not scan all items in the array.Diastyle
@Diastyle Above code's goal is check element in array ,not scan all element of array.Griffiths
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.Diastyle
G
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); 
}
Glint answered 18/12, 2018 at 13:33 Comment(0)
S
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("->");
        }
    }
}
Selfdeprecating answered 16/6, 2021 at 14:48 Comment(0)
D
-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;
}
}
Denotative answered 18/8, 2012 at 17:18 Comment(0)
T
-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;

              }


     }
}
Tortola answered 18/8, 2012 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.