Обробка Значень за Допомогою Класу Optional
Свайпніть щоб показати меню
У Java змінні, які зберігають об'єкти, можуть містити значення null. Це часто призводить до виникнення NullPointerException, якщо null обробляється неналежним чином. Такі помилки знижують надійність коду та ускладнюють його супровід. Саме тут на допомогу приходить Optional.
Уявіть це як коробку — вона може містити значення, або бути порожньою. Замість використання операторів if для перевірки на null, ви працюєте з цією "коробкою" та застосовуєте зручні методи для безпечного отримання значення, якщо воно існує.
Синтаксис і використання Optional
Основна мета Optional — уникнути NullPointerException, замінюючи стандартні перевірки if (value != null) на більш читабельні методи.
Існує три способи створити Optional:
Optional.empty()– створює порожнійOptionalбез значення;Optional.of(value)– обгортає заданий об'єкт, але лише якщо він гарантовано не є null;Optional.ofNullable(value)– обгортає об'єкт, навіть якщо вінnull, створюючи або заповнений, або порожнійOptional.
Main.java
123456789101112131415package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> emptyOpt = Optional.empty(); Optional<String> optWithValue = Optional.of("Laptop"); Optional<String> optNullable = Optional.ofNullable(null); System.out.println("Empty Optional: " + emptyOpt); System.out.println("Optional with value: " + optWithValue); System.out.println("Optional with null: " + optNullable); } }
Якщо передати null у Optional.of(value), програма викине NullPointerException, тому для можливо порожніх значень завжди слід використовувати ofNullable().
Отримання значень з Optional
Для витягання значення з Optional можна використовувати метод get().
Main.java
12345678910package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> optWithValue = Optional.of("Laptop"); System.out.println("Final string: " + optWithValue.get()); } }
Тут get() повертає фактичний об'єкт, що зберігається всередині Optional. Однак, якщо Optional є порожнім (містить null), виклик get() викине NoSuchElementException.
Перевірка наявності значення
Працюючи з Optional, необхідно перевіряти, чи містить він значення. Один зі способів — використання isPresent(), який повертає true, якщо значення присутнє. Однак часто надають перевагу ifPresent(), оскільки він виконує заданий лямбда-вираз лише у разі наявності значення.
Main.java
123456789101112131415161718package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); if (productOpt.isPresent()) { System.out.println("Product found: " + productOpt.get()); } else { System.out.println("Product not found."); } // A more concise approach productOpt.ifPresent(product -> System.out.println("Product: " + product)); } }
У першому прикладі ви вручну перевіряєте наявність значення за допомогою isPresent() перед викликом get(). Другий приклад усуває необхідність у операторі if, використовуючи лямбда-вираз, який виконується лише якщо продукт присутній.
Надання значення за замовчуванням
Іноді, коли значення відсутнє, доцільно повернути альтернативу. Це можна зробити за допомогою orElse(), який надає резервне значення. Якщо для створення резервного значення потрібні обчислення, orElseGet() є більш ефективним, оскільки виконує функцію лише за необхідності.
Main.java
123456789101112131415package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElse("Default product"); System.out.println("Selected product: " + product); String productLazy = productOpt.orElseGet(() -> "Fallback product"); System.out.println("Selected product (lazy): " + productLazy); } }
Відмінність полягає в тому, що orElse() завжди створює резервне значення, навіть якщо воно не потрібне, тоді як orElseGet() викликає надану функцію лише якщо Optional є порожнім.
Генерування винятку, якщо значення відсутнє
У деяких випадках відсутність значення є помилкою. У таких ситуаціях можна використати orElseThrow() для генерування винятку.
Main.java
123456789101112package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable(null); String product = productOpt.orElseThrow(() -> new RuntimeException("Product not found")); System.out.println("Product: " + product); } }
Тут, якщо Optional є порожнім, програма генерує RuntimeException. Це корисно, коли відсутнє значення означає критичну помилку.
Трансформація значень
Часто Optional містить складні об'єкти, але потрібно працювати лише з окремими полями. У таких випадках використовується map(), яка застосовує задану функцію, якщо значення присутнє.
Main.java
123456789101112package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.ofNullable("Laptop"); Optional<Integer> nameLengthOpt = productOpt.map(String::length); nameLengthOpt.ifPresent(length -> System.out.println("Product name length: " + length)); } }
Якщо Optional є порожнім, map() просто повертає Optional.empty(). В іншому випадку застосовується String::length і повертається Optional<Integer>.
Фільтрація значень
Іноді потрібно зберегти значення лише якщо воно відповідає певній умові. Метод filter() допомагає, залишаючи значення, якщо заданий предикат повертає true, або повертаючи Optional.empty(), якщо умова не виконується.
Main.java
123456789101112package com.example; import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> productOpt = Optional.of("Laptop"); Optional<String> filteredProductOpt = productOpt.filter(name -> name.length() > 5); filteredProductOpt.ifPresent(name -> System.out.println("Filtered product: " + name)); } }
Якщо довжина рядка більша за 5, значення зберігається; інакше Optional стає порожнім.
1. Що відбувається, якщо викликати get() для порожнього Optional?
2. Що виведе цей код?
3. Яким буде результат виконання наступного коду?
4. Який метод найкраще підходить для надання значення за замовчуванням, яке обчислюється лише за потреби?
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат