Поиск метода indexOf в массивах Java: решения и альтернативы
Быстрый ответ
В Java не существует встроенного метода indexOf
для массивов. Вам придется самостоятельно реализовать фунциональность этого метода. Это можно сделать так:
public static int indexOf(int[] array, int key) {
for (int i = 0; i < array.length; i++) {
if (array[i] == key) return i;
}
return -1;
}
Применим его на практике:
int index = indexOf(new int[]{1, 2, 3, 4}, 3); // вернёт 2
Примитивные массивы против объектных массивов
В случае примитивных массивов...
Метод Arrays.asList()
будет работать неадекватно с примитивными массивами, трактуя весь массив как единый объект.
Преобразуйте примитивы в объекты следующим образом:
Integer[] boxedArray = {1, 2, 3, 4};
int index = Arrays.asList(boxedArray).indexOf(3); // возвращает 2
С отсортированными массивами всё как с конфетами в коробке
Для работы с отсортированными массивами можно использовать метод Arrays.binarySearch()
, который является крайне эффективным – его сложность составляет O(log n):
int[] sortedArray = {1, 2, 3, 4};
int index = Arrays.binarySearch(sortedArray, 3);
if (index >= 0) {
// элемент найден
} else {
// в массиве данный элемент отсутствует
}
Получение отрицательного результата говорит об отсутствии искомого элемента.
Встреча массивов с Коллекциями
Массивы стали более социальными
Используя Arrays.asList()
, массивы могут успешно взаимодействовать с другими коллекциями и использовать такие методы как indexOf
и lastIndexOf
:
List<Integer> list = Arrays.asList(1, 2, 3, 4);
int index = list.indexOf(3); // возвращает 2
Заметим, что размер такого списка изменить нельзя.
Встроенный метод indexOf
в библиотеках сторонних разработчиков
Существуют сторонние библиотеки, такие как Apache Commons Lang и Guava, предоставляющие встроенный indexOf
:
- В Apache Commons Lang это метод
ArrayUtils.indexOf()
:
int index = ArrayUtils.indexOf(new int[]{1, 2, 3, 4}, 3); // возвращает 2
- В Guava для работы с примитивами применяется
Ints.indexOf()
:
int index = Ints.indexOf(new int[]{1, 2, 3, 4}, 3); // возвращает 2
Создание вашего собственного indexOf
Ваш персональный метод
Вы можете создать свой собственный метод indexOf
, который будет выполнять проверку на null
и иметь настраиваемое поведение:
public static <T> int indexOf(T[] array, T key) {
if (key == null) {
for (int i = 0; i < array.length; i++) {
if (array[i] == null) return i;
}
} else {
for (int i = 0; i < array.length; i++) {
if (key.equals(array[i])) return i;
}
}
return -1;
}
Сортировка по-своему с использованием Comparator
Вы можете использовать Comparator
для работы с методом Arrays.binarySearch()
:
Integer[] array = {2, 4, 1, 3};
Arrays.sort(array, Comparator.reverseOrder());
int index = Arrays.binarySearch(array, 3, Comparator.reverseOrder()); // возвращает 2
Визуализация
Допустим, мы ищем любимую книгу (📗) в библиотеке:
String[] bookshelf = {"📘", "📙", "📕", "📗", "📔"};
int favoriteBookIndex = Arrays.asList(bookshelf).indexOf("📗"); // 🕵️♂️
Мы искали книгу среди остальных и нашли её на позиции: 3.
Несмотря на то, что Java не предоставляет метод indexOf
для массивов, проблема легко решается с помощью конструкции Arrays.asList(array).indexOf(element)
.
Жонглирование производительностью
Выбор метода имеет значение
- Для небольших массивов подходит обычный цикл
for
. - Для отсортированных массивов большого размера подойдет
binarySearch
. - При работе с примитивами, такими библиотеками как Guava, можно добиться более высокой эффективности.
Stream API для стиля и производительности
В Java 8 возможно использовать такой подход:
int index = IntStream.range(0, array.length)
.filter(i -> key.equals(array[i]))
.findFirst()
.orElse(-1); // вернёт 2
Полезные материалы
- [Arrays (Java Platform SE 8)] — документация по работе с массивами.
- [List (Java Platform SE 8)] — интерфейс List.
- [ArrayUtils (Apache Commons Lang 3.11 API)] — библиотека Apache Commons Lang.
- [FluentIterable (Guava)] — библиотека Google Guava.
- [Where is Java's Array indexOf? – Stack Overflow] — обсуждение на форуме Stack Overflow.
- [Stream (Java Platform SE 8)] — Java Stream API.
- [IntStream (Java Platform SE 8)] — IntStream для удобной работы с массивами примитивов.