Разбираемся с Optional в java

Optional — это объект который может содержать или не содержать значения. Такой себе код шредингера в java.

Представлен данный класс был с выходом java 8 и признаюсь Вам честно — я не сильно обращал внимания на данный объект до недавнего времени.

Как мы обычно проверяем объект на значение null?


import java.util.Arrays;
import java.util.List;

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1);
        
        users.forEach(it -> {
            if (it != null) {
                //do something with 
            }
        });
    }
    
}

class User {
    String name;
    String email;
}

Выше — типичный пример проверки объекта на значение его поля на нулл.

С помощью Optional можно писать значительно короче и красивее.

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1, null);

        users.forEach(it -> {
            Optional.ofNullable(it).orElse(new User());
        });
    }

}

class User {
    String name;
    String email;
}

И это еще не все. Данный класс может возвращать стримы, которые можно использовать в дальнейшей работе. Давайте я покажу пару примеров:

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1, null);

        users.forEach(it -> {
            System.out.println(Optional
                    .ofNullable(it)
                    .map(u -> "Hi " + u.name)
                    .orElse("Hi guest"));
        });
    }

}

class User {
    String name;
    String email;
}

Результатом выполнения кода будут строки:

Hi testName
Hi null
Hi guest

Почему вторая строка не выдала нам Hi guest?

Дело в том, что мы проверяем на нулл значение user, но совсем не проверяем значение name в данном объекте.

Если не использовать Optional то корректно будет работать такой код:

import java.util.Arrays;
import java.util.List;

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1, null);

        users.forEach(it -> {
            if(it!=null){
                if(it.name!=null){
                    System.out.println("Hi " + it.name);
                }else{
                    System.out.println("Hi guest");
                }
            }else{
                System.out.println("Hi guest");
            }
        });
    }

}

class User {
    String name;
    String email;
}

Да! Этот код будет работать. Да. Он вполне себе читаемый и его можно использовать. Но, сегодня мы изучаем Optional и увидим, как его можно переписать на современный лад.

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1, null);

        users.forEach(it -> {
            System.out.println("Hi " + Optional.ofNullable(it).map(u -> u.name).orElse("guest"));
        });
    }

}

class User {
    String name;
    String email;
}

Одна строчка! Всего одна строка, КАРЛ!

Я понимаю, что данный пример плохо подходит для боевых условий и реальная задача может быть не настолько тривиальна, но все же.

Это еще не все фишки Optional. Он также может выбрасывать исключения вместо возвращения каких то дефолтных значений.

public class Example {

    public static void main(String[] args) {
        User user = new User();
        user.email = "testEmail";
        user.name = "testName";
        User user1 = new User();
        List<User> users = Arrays.asList(user, user1, null);

        users.forEach(it -> {
            try {
                Optional.ofNullable(it).orElseThrow(Exception::new);
            } catch (Exception e) {
                System.out.println("User not found");
                e.printStackTrace();
            }
        });
    }

}

class User {
    String name;
    String email;
}

На этом и все. С данным классом нужно работать, чтобы понять всю его пользу и простоту.

Бери себе на вооружение и удивляй коллег своими джедайскими способностями написания кода. Если ты этого не будешь знать — коллеги будут думать, что ты динозавр. Шучу;)

Класс на самом деле очень полезен и совсем не сложный. Бери примеры кода, практикуйся и применяй на своем проекте!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *