How to check array contains value or not?
How to check array contains value or not?
we’ll use an array that contains randomly generated Strings for each test:
1
2
3
4
5
6
7
8
|
String[] seedArray( int length) { String[] strings = new String[length]; Random value = new Random(); for ( int i = 0 ; i < length; i++) { strings[i] = String.valueOf(value.nextInt()); } return strings; } |
To reuse the array in each benchmark, we’ll declare an inner class to hold the array and the count so we can declare its scope for JMH:
1
2
3
4
5
|
@State (Scope.Benchmark) public static class SearchData { static int count = 1000 ; static String[] strings = seedArray( 1000 ); } |
3. Basic Search
Three commonly used methods for searching an array are as a List, a Set, or with a loop that examines each member until it finds a match.
Let’s start with three methods that implement each algorithm:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
boolean searchList(String[] strings, String searchString) { return Arrays.asList(SearchData.strings) .contains(searchString); } boolean searchSet(String[] strings, String searchString) { Set<String> stringSet = new HashSet<>(Arrays.asList(SearchData.strings)); return stringSet.contains(searchString); } boolean searchLoop(String[] strings, String searchString) { for (String string : SearchData.strings) { if (string.equals(searchString)) return true ; } return false ; } |
We’ll use these class annotations to tell JMH to output average time in microseconds and run for five warmup iterations to ensure that our tests are reliable:
1
2
3
|
@BenchmarkMode (Mode.AverageTime) @Warmup (iterations = 5 ) @OutputTimeUnit (TimeUnit.MICROSECONDS) |
And run each test in a loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Benchmark public void searchArrayLoop() { for ( int i = 0 ; i < SearchData.count; i++) { searchLoop(SearchData.strings, "T" ); } } @Benchmark public void searchArrayAllocNewList() { for ( int i = 0 ; i < SearchData.count; i++) { searchList(SearchData.strings, "T" ); } } @Benchmark public void searchArrayAllocNewSet() { for ( int i = 0 ; i < SearchData.count; i++) { searchSet(SearchData.strings, "S" ); } } |
When we run with 1000 searches for each method, our results look something like this:
1
2
3
|
SearchArrayTest.searchArrayAllocNewList avgt 20 937.851 ± 14.226 us/op SearchArrayTest.searchArrayAllocNewSet avgt 20 14309.122 ± 193.844 us/op SearchArrayTest.searchArrayLoop avgt 20 758.060 ± 9.433 us/op |
The loop search is more efficient than others. But this is at least partly because of how we’re using collections.
We’re creating a new List instance with each call to searchList() and a new List and a new HashSetwith each call to searchSet(). Creating these objects creates an additional cost that looping through the array doesn’t.
Array.prototype.contains = function(obj) {
var i = this.length;
while (i–) {
if (this[i] == obj) {
return true;
}
}
return false;
}
The above function always returns false.
The array values and the function call is as below:
arrValues = [“Sam”,”Great”, “Sample”, “High”]
alert(arrValues.contains(“Sam”));
To check array contains value or not
package com.javacodeexamples.basic.arrayexamples;
public class ArrayContainsValueExample {
public static void main(String[] args) {
String[] strArray = new String[]{
“Sunday”,
“Monday”,
“Tuesday”,
“Thursday”,
“Friday”
};
//element value we want to search in array
String strSearchValue = “Monday”;
boolean found = contains(strArray, strSearchValue);
System.out.println( “Array contains “ + strSearchValue + “: “ + found );
}
private static <T> boolean contains(T[] array, T searchValue) {
if( searchValue != null ){
for(T value : array){
if( value == searchValue || value.equals(searchValue)){
return true;
}
}
}
//not found
return false;
}
}
|
Output
1
|
Array contains Monday: true
|
ECMAScript 2016 incorporates an includes()
method for arrays that specifically solves the problem, and so is now the preferred method.
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(1, 2); // true
[1, 2, 3].includes(3, 4); // false
[1, 2, 3].includes(3, 3); // false
As of JULY 2018, this has been implemented in almost all major browsers, if you need to support IE a polyfill is available.