Як вже обговорювалося , розробники API не припускають, що розробник хоче nullоднаково ставитись до значень та відсутніх значень.
Якщо ви все одно хочете зробити це, ви можете зробити це явно, застосувавши послідовність
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
до потоку. Результат буде порожнім необов’язковим в обох випадках, якщо немає першого елемента або якщо перший елемент є null. Тож у вашому випадку ви можете використовувати
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
.orElse(null);
отримати nullзначення, якщо перший елемент або відсутній, або null.
Якщо ви хочете розрізнити ці випадки, ви можете просто пропустити flatMapкрок:
Optional<String> firstString = strings.stream()
.map(Optional::ofNullable).findFirst().orElse(null);
System.out.println(firstString==null? "no such element":
firstString.orElse("first element is null"));
Це мало чим відрізняється від вашого оновленого запитання. Вам просто потрібно замінити "no such element"на "StringWhenListIsEmpty"і "first element is null"з null. Але якщо вам не подобаються умови, ви можете досягти цього також, як:
String firstString = strings.stream().skip(0)
.map(Optional::ofNullable).findFirst()
.orElseGet(()->Optional.of("StringWhenListIsEmpty"))
.orElse(null);
Тепер firstStringбуде, nullякщо елемент існує, але є, nullі буде, "StringWhenListIsEmpty"коли жодного елемента не існує.