ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java Optional2
    JAVA 2022. 2. 3. 15:28

    <피드백 언제나 환영합니다! 댓글 달아주세요 감사합니다>

    Java Optional 1 에서 정확한 설명을 하지 못해서 보충 설명 및 사용시 주의사항 위주로 이야기 해보려고 합니다.

    • orElse, orElseGet두 메소드의 차이점을 쉽게 생각하려다보니 놓친 부분이 있다.orElseGet(Supplier ...) → other.get()이 실행이된다 → value 값이 null 인 경우에 method 가 실행이 되는형태 (method 가 들어온 형태라면)
    • orElse(T other) → 안에 있는 값이 무조건 실행되는걸 확인할 수있다. 즉, println() 과 같은 형태이다. 즉 T other 에 method가 들어간 형태이기 때문 (반환값이 있는)
    • Optional.steam() 통해 스트림을 생성(Java 9부터 추가) → Optional은 stream용 메서드가 아니다.

    Java Optional 주의사항

    앞전에도 말했듯이 Optional은 Wrapper class 입니다 → Wrapper class 는 비용문제가 발생 → 객체 생성, 참조 비용...

    primitive type 비해 비싸다 필요할 때만 써야합니다. Effective Java 에서 Optional 활용에 따르면

    • Optional 활용1 - 기본값(defalut)를 정해둘 수 있다.
      • optionalS1.orElse(”이름 없음”);
    • Optional 활용2 - 원하는 예외를 던질 수 있다.
      • 값이 없는경우 원하는 예외를 던져 사용이 가능하다
      • optionalS1.orElseThrow(Exception::new);
    • Optional 활용3 - 항상 값이 채워져 있는 경우
      • .get()을 이용하여 출력 → 값이 있다고 확신이 들때만 사용
    • Optional 활용4 - 기본값을 설정하는 비용이 큰 경우
      • 활용1 에서 기본값 비용이 클경우 사용

    Java Optional 안티 패턴

    • Collection, Stream, 배열은 Optional로 되도록이면 감싸지 말자
      • List 는 값을 담아두는 그릇 → 빈 ArrayList를 반환하면 된다. → Optional 처리코드를 넣지 않아도 된다.
    • Optional을 Map의 키나 값으로 사용 금지
      • key 자체가 없는경우
      • key는 있지만, 속이 빈 Optional 인경우
      → 쓸데없이 복잡도만 높아지게되고 쓸모없는짓중 하나입니다.
    • isPresent() 를 사용하지 말자
      • if 문을 벗어나기위해 Optional을 사용한거다.. 이점을 꼭 생각해야 한다.

    추가적으로 알아야 할 것들

    • 박싱된 기본타입 사용시 → OptionalInt, OptionalDouble, OptionalLong 사용
    • 값을 반환하지 못할 가능성이 있고, 호출할 때마다 반환값이 없을 가능성을 염두에 둬야하는 메소드 → Optional을 반환해야하는 상황일 수 있다. (JpaRepository save() 같은 기능들)

    추가 Optional Method

    Java Optional 1 :: Eco 의 개발일기 에서 get(), orElseThorw(), orElse(), orElseGet()외 다른 method를 확인 해보겠습니다.

    • 예제 class
      @Data
      static class Team{
      	Subject subject;
      	List<Member> memberList;
      }
      @Data
      static class Subject{
      	String gameName;
      }
      @Data
      static class Member {
      	Long id;
      	String name;
      	String email;
      }
    • void ifPresent(Consumer<? super T> consumer)
      • Optional 내부의 값이 있는 경우 consumer 함수를 실행
    • Optional<T> filter(Predicate<T> predicate)
      • Optional에 filter 조건을 걸어 조건에 맞을 때만 Optional 내부 값이 있음
      • 조건이 맞지 않으면 Optional.empty를 리턴
      • Optional.filter() 예제
        Member member1 = new Member(1L, "hello1");
        Member member2 = new Member(null, null);
        List<Member> memberList = new ArrayList<>(List.of(member1, member2));
        
        Subject subject = new Subject();
        subject.setGameName("LOL");
        
        Team team = new Team();
        team.setMembers(memberList);
        team.setSubject(subject);
        Team team1 = Optional.ofNullable(team)
                .filter(item -> item.getSubject().getGameName().equals("LOL"))
                .orElse(null);
        System.out.println("team1 = " + team1);
        /*team1 = OptionalJava.Team(subject=OptionalJava.Subject(gameName=LOL), 
        					members=[OptionalJava.Member(id=1, name=hello1, email=null), 
        										OptionalJava.Member(id=null, name=null, email=null)])
        /*
    • Optional<U> map(Funtion<? super T, ? extends U> f)
      • Optional 내부의 값을 Function을 통해 가공
      • Optional.empty를 리턴
      • Optional.map() 예제
        Team team = new Team();
        String gameObject = Optional.ofNullable(team)
        								.map(Team::getSubject)
                        .map(Subject::getGameName)
                        .orElse("game 종목이 없네");
        System.out.println("gameObject = " + gameObject );
        /* 게임종목이 없네/*
    • Stream을 이용한 Optional중간에 비어있는 Optional 객체가 반환되는 경우, Stream.empty()가 반환되며 함수 체이닝이 더 이상 진행되지 않는점을 유의하자. 스트림 연산이 멈춘다.
      • Stream 예제 코드
        List.of(4, 3, 2, 5)
        		.stream() // stream으로 복사해서 사용가능하다.
        		.map(value -> value > 2 ? Optional.of(value) : Optional.empty())
        		.flatMap(Optional::stream)
        		.forEach(System.out::println);
        /* 3
        	 4
        	 5 */
      물론 람다식과 메서드 레퍼런스는 선택사항이다. 꼭 필요하다면 익명클래스를 사용해도 상관없다.

    참고

     

    'JAVA' 카테고리의 다른 글

    Pattern  (0) 2022.02.15
    Java Optional 1  (0) 2022.01.25

    댓글

Designed by Tistory.