1. Обзор
Поиск элемента в списке-очень распространенная задача, с которой мы сталкиваемся как разработчики.
В этом кратком руководстве мы рассмотрим различные способы, которыми мы можем сделать это с помощью Java.
Дальнейшее чтение:
Проверка Сортировки списка в Java
Инициализация списка Java в одной строке
2. Настройка
Сначала давайте начнем с определения Customer POJO:
public class Customer { private int id; private String name; // getters/setters, custom hashcode/equals }
Затем ArrayList клиентов:
Listcustomers = new ArrayList<>(); customers.add(new Customer(1, "Jack")); customers.add(new Customer(2, "James")); customers.add(new Customer(3, "Kelly"));
Обратите внимание, что мы переопределили hashCode и equals в нашем классе Customer .
Исходя из нашей текущей реализации equals , два Customer объекта с одинаковым id будут считаться равными.
Мы будем использовать этот список клиентов по пути.
3. Использование Java API
Сама Java предоставляет несколько способов поиска элемента в списке:
- То содержит метод
- То indexOf метод
- Специальный цикл for
- То Течение ИНТЕРФЕЙС ПРИКЛАДНОГО ПРОГРАММИРОВАНИЯ
3.1. содержит()
List предоставляет метод с именем содержит :
boolean contains(Object element)
Как следует из названия, этот метод возвращает true , если список содержит указанный элемент, и возвращает false в противном случае.
Поэтому, когда нам нужно проверить, существует ли конкретный элемент в нашем списке, мы можем:
Customer james = new Customer(2, "James"); if (customers.contains(james)) { // ... }
3.2. Индекс()
indexOf – еще один полезный метод поиска элементов:
int indexOf(Object element)
Этот метод возвращает индекс первого вхождения указанного элемента в данный список или -1, если список не содержит элемента .
Таким образом, логически, если этот метод возвращает что-либо, кроме -1, мы знаем, что список содержит элемент:
if(customers.indexOf(james) != -1) { // ... }
Главное преимущество использования этого метода заключается в том, что он может сообщить нам положение указанного элемента в данном списке.
3.3. Основные циклы
А что, если мы хотим выполнить поиск элемента на основе полей? Например, скажем, мы объявляем лотерею, и нам нужно объявить Клиента с определенным именем победителем.
Для таких полевых поисков мы можем обратиться к итерации.
Традиционный способ итерации по списку-использовать одну из циклических конструкций Java. На каждой итерации мы сравниваем текущий элемент в списке с элементом, который мы ищем, чтобы увидеть, соответствует ли он:
public Customer findUsingEnhancedForLoop( String name, Listcustomers) { for (Customer customer : customers) { if (customer.getName().equals(name)) { return customer; } } return null; }
Здесь имя относится к имени, которое мы ищем в данном списке клиентов . Этот метод возвращает первый Customer объект в списке с соответствующим именем или null , если такого Customer не существует.
3.4. Цикл С итератором
Итератор – это еще один способ обхода списка элементов.
Мы можем просто взять наш предыдущий пример и немного подправить его:
public Customer findUsingIterator( String name, Listcustomers) { Iterator iterator = customers.iterator(); while (iterator.hasNext()) { Customer customer = iterator.next(); if (customer.getName().equals(name)) { return customer; } } return null; }
Следовательно, поведение остается таким же, как и раньше.
3.5. Java 8 Stream API
Начиная с Java 8, мы также можем использовать Stream API для поиска элемента в списке .
Чтобы найти элемент, соответствующий определенным критериям в данном списке, мы:
- вызовите stream() в списке
- вызовите метод f ilter() с соответствующим предикатом
- вызовите конструкцию find Any () , которая возвращает первый элемент, соответствующий предикату filter , завернутому в Optional , если такой элемент существует
Customer james = customers.stream() .filter(customer -> "James".equals(customer.getName())) .findAny() .orElse(null);
Для удобства мы по умолчанию используем значение null в случае, если Необязательный пуст, но это не всегда может быть лучшим выбором для каждого сценария.
4. Сторонние Библиотеки
Теперь, хотя Stream API более чем достаточен, что нам делать, если мы застряли на более ранней версии Java?
К счастью, есть много сторонних библиотек, таких как Google Guava и Apache Commons, которые мы можем использовать.
4.1. Google Guava
Google Guava предоставляет функциональность, похожую на то, что мы можем сделать с потоками:
Customer james = Iterables.tryFind(customers, new Predicate() { public boolean apply(Customer customer) { return "James".equals(customer.getName()); } }).orNull();
Как и в случае с Stream API, мы можем дополнительно выбрать возврат значения по умолчанию вместо null :
Customer james = Iterables.tryFind(customers, new Predicate() { public boolean apply(Customer customer) { return "James".equals(customer.getName()); } }).or(customers.get(0));
Приведенный выше код выберет первый элемент в списке, если совпадение не будет найдено.
Кроме того, не забывайте, что Гуава бросает Исключение NullPointerException если либо список, либо предикат нулевой .
4.2. Apache Commons
Мы можем найти элемент почти точно таким же образом, используя Apache Commons:
Customer james = IterableUtils.find(customers, new Predicate() { public boolean evaluate(Customer customer) { return "James".equals(customer.getName()); } });
Однако есть несколько важных отличий:
- Apache Commons просто возвращает null , если мы передаем список null .
- Оно не обеспечивает функциональность значений по умолчанию, как у Guava попробуй Найти.
5. Заключение
В этой статье мы изучили различные способы поиска элемента в списке , начиная с быстрых проверок существования и заканчивая полевыми поисками.
Мы также рассмотрели сторонние библиотеки Google Guava и Apache Commons как альтернативы Java 8 Streams API.
Спасибо, что заглянули, и не забудьте проверить все источники для этих примеров на GitHub.