Выберите один элемент
Интуитивно, выбор одного элемента определенно проще, чем выбор нескольких элементов, но здесь есть некоторые проблемы. Давайте сначала посмотрим, в чем проблема с общим подходом, а затем посмотрим, как использовать лямбда-выражения для ее решения.
Давайте сначала создадим новый метод для поиска элемента, начинающегося с определенной буквы, а затем распечатаем его.
Скопируйте код кода следующим образом:
public static void PickName(
окончательные имена List<String>, окончательная строка startLetter) {
Строка найденоИмя = ноль;
for(Имя строки: имена) {
если (name.startsWith (startingLetter)) {
найденноеИмя = имя;
перерыв;
}
}
Этот метод вонючий, как только что проехавший мусоровоз. Сначала мы создали новую переменную FoundName, а затем инициализировали ее нулевым значением — это источник зловония. Мы должны проверить, является ли оно нулевым, иначе будет выдано исключение NullPointerException или ответ об ошибке. Мы также используем внешний итератор для цикла по списку. Если мы находим нужный элемент, нам приходится выходить из цикла, что добавляет исходного запаха: паранойя базового типа, императивный стиль, изменчивость — все оживает. После выхода из цикла нам нужно проверить результаты перед печатью. Такая маленькая задача на самом деле требует такого длинного кода.
Давайте еще раз проанализируем этот вопрос. Мы просто хотим иметь возможность выбрать первый соответствующий элемент и безопасно обработать случай, когда такой элемент не существует. Давайте перепишем этот метод PickName, используя лямбда-выражение.
Скопируйте код кода следующим образом:
public static void PickName(
окончательные имена List<String>, окончательная строка startLetter) {
Final Необязательный<String> FoundName =
имена.поток()
.filter(имя ->name.startsWith(startingLetter))
.findFirst();
System.out.println(String.format("Имя, начинающееся с %s: %s",
startLetter, FoundName.orElse("Имя не найдено")));
}
Некоторые мощные функции JDK делают этот код очень кратким. Сначала мы используем метод фильтра для получения всех элементов, соответствующих условиям, а затем используем метод findFirst класса Stream для выбора первого элемента возвращаемой коллекции. Этот метод возвращает необязательный объект, который является официально сертифицированным дезодоратором для нулевых переменных в Java.
Класс Необязательный очень полезен, вам не нужно беспокоиться о том, существует результат или нет. Это избавляет нас от проблем, связанных с исключениями нулевого указателя, и дает понять, что отсутствие результата не является возможным. С помощью метода isPresent() мы можем узнать, существует ли результат. Если мы хотим получить значение результата, мы можем использовать метод get(). Мы также можем установить для него значение по умолчанию, используя (название этого метода вас шокирует) метод orElse, как и в предыдущем коде.
Мы используем коллекцию друзей, которую использовали раньше, для проверки нашего метода PickName.
Скопируйте код кода следующим образом:
PickName(друзья, "N");
PickName(друзья, "Z");
Этот код выбирает первый соответствующий элемент и печатает дружественное сообщение, если он не найден.
Скопируйте код кода следующим образом:
Имя на букву Н: Нейт.
Имя, начинающееся с Z: Имя не найдено.
Комбинация метода findFirst() и класса Optinal уменьшает объем нашего кода и выглядит хорошо. Но функции класса «Дополнительный» — это гораздо больше. Например, помимо предоставления значения по умолчанию, когда объект не существует, вы также можете использовать его для запуска фрагмента кода или лямбда-выражения, если результат существует, например:
Скопируйте код кода следующим образом:
FoundName.ifPresent(name -> System.out.println("Привет " + имя));
По сравнению с императивным кодом выбора первого совпадающего имени элегантный функциональный стиль потока выглядит лучше. Но не слишком ли много дел нужно сделать в этой версии потока вызовов? Конечно, нет, эти методы очень умны и работают по требованию (мы подробно рассмотрим это в разделе «Отложенная оценка потоков» на стр. 113).
На примере выбора одного элемента показаны более мощные функции библиотеки JDK. Давайте посмотрим, как лямбда-выражения могут найти нужное значение на основе коллекции.