Working on getting your persistence layer right with Spring?
Find the Index of an Element in a Java Array
Last updated: October 5, 2023
1. Overview
In this tutorial, we’ll discuss various methods, with code examples, for finding the index of an array element using both Java’s built-in APIs and a third-party library. This can be useful for many tasks, including searching, sorting, and modifying arrays.
2. Using a for Loop
Our first approach is one of the easiest ways to find the index of an element in an array. This is by using a for loop.
The idea is to iterate over the input array and check the element in each iteration. If the element is found, then we return the current index.
Otherwise, if we can’t find the element at the end of the array, we return a fixed constant value. This fixed value could be anything we know beforehand. We use it to indicate that the element wasn’t found in the array.
Examples of these fixed constant values are -1, Integer.MAX_VALUE, Integer.MIN_VALUE, etc.
First, let’s create a simple method using this approach:
int forLoop(int[] numbers, int target) {
for (int index = 0; index < numbers.length; index++) {
if (numbers[index] == target) {
return index;
}
}
return -1;
}
We iterate over the input numbers array and then check each element. If we find a match, we return the current index value. Otherwise, we return -1, indicating that we can’t find the target.
Now let’s test our forLoop() method with some sample input data:
@Test
void givenIntegerArray_whenUseForLoop_thenWillGetElementIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(2, forLoop(numbers, 30));
}
Here, we’re looking for the value 30. The forLoop() method returns 2, the position in the input array. We must remember that an array’s start index is zero in Java.
Next, let’s look for an element that’s not in the input array:
@Test
void givenIntegerArray_whenUseForLoop_thenWillGetElementMinusOneIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-1, forLoop(numbers, 100));
}
In this case, we try to search for the number 100. However, it’s not present in our array. That’s why our method returns -1, indicating that the element wasn’t found.
3. Using List indexOf()
We’ll use the indexOf() method from the List class for the next approach:
static int listIndexOf(Integer[] numbers, int target) {
List<Integer> list = Arrays.asList(numbers);
return list.indexOf(target);
}
In our listIndexOf() method, we pass an Integer array and a target value as arguments. Under the hood, we use the asList() method from the Arrays utility class. This method converts object arrays into a List of the same object type. Notably, the asList() method doesn’t have any implementation for primitive types.
After the input array is converted into a list, we use the indexOf() method to find the index of our target element. If the target element isn’t in the list, then the indexOf() method returns -1.
Now, let’s implement a couple of test cases. In the first one, the target will be in the input array:
@Test
void givenIntegerArray_whenUseIndexOf_thenWillGetElementIndex() {
Integer[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(2, listIndexOf(numbers, 30));
}
When we call our listIndexOf() method, we get index 2, the position in the input array for the target number 30.
In the second test case, the target element isn’t in the input array:
@Test
void givenIntegerArray_whenUseIndexOf_thenWillGetElementMinusOneIndex() {
Integer[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-1, listIndexOf(numbers, 100));
}
In this case, we get the expected result, -1.
4. Using Arrays binarySearch()
Another helpful method from the Arrays utility class is the binarySearch() method. This method executes the binary search algorithm. The input array must be sorted before using this method. We can use the binarySearch() method to find the index of an element in a sorted array.
Let’s implement some tests using the binarySearch() method:
@Test
void givenIntegerArray_whenUseBinarySearch_thenWillGetElementIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(2, Arrays.binarySearch(numbers, 30));
}
Using the binarySearch() method in the above code, the method returns its index number if the target element is found. In this case, we get the index 2.
However, the method returns a negative value if the target isn’t found. According to the official documentation for the binarySearch() method in Java, this negative value is calculated using an insertion point. The insertion point is where the key would go in the array. Its value is the index of the first element bigger than the key or arr.length if all the elements in the array are smaller than the key. The index when the element isn’t in the array is equal to (-(insertion point)-1).
Let’s implement a couple of tests about this negative value:
@Test
void givenIntegerArray_whenUseBinarySearch_thenWillGetUpperBoundMinusIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-6, Arrays.binarySearch(numbers, 100));
}
Since 100 is not in the array, the method returns a negative value. In this case, the returned value is -6. This is because all the elements in the array are smaller than our target value. Then, the insertion point is 5 (array length), and the resulting index is (-5-1), which is -6.
Another case is when the target element value is between the upper and lower bounds values of the array:
@Test
void givenIntegerArray_whenUseBinarySearch_thenWillGetInArrayMinusIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-2, Arrays.binarySearch(numbers, 15));
}
In the above test case, since 15 is a value between 10 and 50, the bounds values for this array, we get the index value -2. We get this value because the insertion point is 1. Thus, the resulting index is (-1-1) or -2.
The last case for this method is when the target value isn’t present and is less than the smallest value in the array:
@Test
void givenIntegerArray_whenUseBinarySearch_thenWillGetLowerBoundMinusIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-1, Arrays.binarySearch(numbers, -15));
}
In this case, we get -1 because our target value is less than the smallest value in the array.
5. Using IntStream
In the following test code, we’ll use the IntStream interface. This interface was introduced in Java 8. From the IntStream interface, we’ll use the range() method. The range() method produces an ordered stream of integers from 0 (inclusive) to arr.length (exclusive).
First, we’ll implement a method using IntStream.range() to iterate over the input array:
static int intStream(int[] numbers, int target) {
return IntStream.range(0, numbers.length)
.filter(i -> numbers[i] == target)
.findFirst()
.orElse(-1);
}
The integers produced by the range() method represent the indices of the numbers array. Then the filter() method checks if the element at index i equals the target value. If the target element isn’t in the array, then orElse() returns -1. Finally, with the findFirst(), we get the first element equal to the target value.
Using our intStream() method, we can implement the next test case:
@Test
void givenIntegerArray_whenUseIntStream_thenWillGetElementIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(2, intStream(numbers, 30));
}
In our test code, we call the intStream() method that we implemented, and we get the index where the target element is placed. If the target element isn’t in the array, then we’ll get -1;
6. Apache Commons Library
At this point, we’ve looked at most of the built-in Java APIs that we can use to find the index of an element in an array. However, there are third-party libraries that we can use to find the index of an element in an array.
A useful third-party library to accomplish our desired behavior is Apache Commons Lang 3. Before we implement our test cases, we need to add the Apache Commons Lang dependency to our pom.xml file:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
In our test cases, we use the indexOf() method from the ArrayUtils class. This method receives as arguments an array and a value to find. Additionally, we can pass a third optional argument, the starting index.
First, let’s test this method by passing the array and the target value:
@Test
void givenIntegerArray_whenUseApacheCommons_thenWillGetElementIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(2, ArrayUtils.indexOf(numbers, 30));
}
In the above test case, we look for a target value of 30. After executing the test, we get the expected value of 2.
In the second test case, we pass the start index for the indexOf() method. Our target value is the same as the first test, and the start index will be 3:
@Test
void givenIntegerArray_whenUseApacheCommonsStartingFromIndex_thenWillGetNegativeIndex() {
int[] numbers = { 10, 20, 30, 40, 50 };
assertEquals(-1, ArrayUtils.indexOf(numbers, 30, 3));
}
After setting the start position to 3, we notice that the target value can’t be found because indexOf() starts at the value 40 in the array. Then after executing the test, we get a -1 index, indicating that the value isn’t in the collection.
7. Performance Comparison
Finally, we’ll quickly review our solutions’ performance using Big O notation from algorithm complexity analysis:
Approaches | Complexity(Big O) | |
Time | Space | |
for loop | O(n) | O(1) |
List indexOf() | O(n) | O(n) |
Arrays binarySearch() | O(log n) | O(1) |
IntStream | O(n) | O(1) |
Apache Commons indexOf() | O(n) | O(1) |
All solutions we have seen have O(n) time complexity, except for the case of the binary search, which has O(log n). However, in the case of the binary search, the input array must be sorted prior.
In the case of space complexity, all solutions have O(1) or constant time complexity except for the case of the listIndexOf() method, which is O(n). In the case of the latter approach, the space complexity comes from the conversion of the input array into a list.
8. Conclusion
In this article, we implemented some methods to find the index of an element in a Java array. We used Java built-in APIs and Apache Commons as a third-party library. Additionally, we performed a time-space complexity analysis of our solutions.
It’s essential to carefully evaluate these libraries’ features and performance characteristics before deciding which one to use in your application.
As always, all code snippets used in this article are available over on GitHub.