본문으로 바로가기

Java8 Optional이란?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class OptionalTest {
    @Test
    public void optionalEmpty() throws Exception {
        Optional<Integer> hello = Optional.empty();
 
        System.out.println(hello.get());
        System.out.println(hello.isPresent());
        hello.ifPresent(item -> System.out.println(item));
    }
 
    @Test
    public void hello() throws Exception {
        Optional<Integer> hello = Optional.empty();
        hello.ofNullable(null);
 
        System.out.println(hello);
    }
}
cs

코드1


Optional은 Java8에서 Java의 Null Pointer Exception을 피하기 위해 만든 클래스이다.


직접 쓰기 보다는 method를 만들 때 Optional로 감싸주면 Null Pointer Exception을 예방 할 수 있다.


1
2
3
4
5
private Optional<Thread> findThreadByName(long gameId){
        return Thread.getAllStackTraces().keySet().stream()
                .filter(thread -> String.valueOf(gameId).equals(thread.getName()))
                .findAny();
}
cs


위와 같이 Thread를 Return하는 예제인데 찾은 Thread가 없을 경우 Optional로 감싸주면 뒤에서 처리하기가 좋다.


코드1의 optionalEmpty()는 실행하면 java.util.NoSuchElementException: No value present 에러가 난다.


Optional이 Empty인 상태에서 .get()을 쓰면 에러가 나기 때문에 .isPresent()로 체크를 한 뒤에 쓰거나


[코드1]의 8번줄 처럼 .ifPresent(Consumer) 를 써준다.


동작은 if(Optional == null){}과 유사하게 작동 하지만 Optional을 써주면 좀 더 깔끔하게 처리 된다.


Java8 Optional쓰는 법


1
2
3
4
5
6
7
UserDetailInfo USERDetailInfo1 = new UserDetailInfo();
String aa = Optional.ofNullable(USERDetailInfo1)
        .map(UserDetailInfo::getOrg)
        .map(Org::getLocation)
        .map(Location::getName)
        .orElse("");
assertEquals("", aa);
cs

이제 앱을 새로 개발을 하면 null을 최대한 안쓰고자 노력을 하는 중이다.


jackson으로 json을 pojo에 매핑해서 쓰는 경우가 많은데 json에 2레벨, 3레벨에 데이터가 없는 경우 NPE(Null Pointer Exception)가 나는 경우가 많다.


그래서 이걸 Optional을 안쓰고 하려면 각각 .get을 할 때마다 if(obj != null) 을 해주어야 하는데 이게 단계가 깊어지면 코드가 지저분해져서 처리 하기가 복잡해지고 배포를 하고 나서 장애가 난 후에야 비로소 코딩을 안하게 되는 문제가 있다.


그래서 Optional을 쓰면 .map()이걸로 하면 각 단계에서 Optional<Org>, Optional<Location>이 리턴 되고 마지막 .orElse()에서 default로 ""를 넣어 주기 때문에


String aa에 null이 들어갈 일이 없다.(믿자 믿습니다.)



Java8 Stream sort(정렬)


.sort()와 Comparator를 사용한다.

1
2
3
List<Vote> votes = new ArrayList<>();
 
votes.sort(Comparator.comparing(Vote::getSum).reversed());
cs


sum을 기준으로 내림차순 정렬


조건 2개일 때

1
2
3
4
5
List<Vote> votes = new ArrayList<>();
 
votess.sort(Comparator.comparing(Vote::getSum).reversed()
                .thenComparing(Comparator.comparing(Vote::getName).reversed())
        );
cs


java8 function이란?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Integer getInteger(String string) {
   return Integer.parseInt(string);
}
 
Function<String, Integer> getInteger2 = str -> Integer.parseInt(str);
 
@Test
public void function() {
   int result = getInteger("10");
   int result2 = getInteger2.apply("10");
 
   System.out.println(result);
   System.out.println(result2);
 
}
cs


1~3번 줄과 같은 형태의 string을 받아서 int를 리턴하는 식의 메소드를 많이 많드는데 이걸 인터페이스로 빼놓은게 function이다.


좀 특이한점은 .apply()로 실행을 한다는 것이다. 람다는 일종의 익명클래스라서 익명클래스 안에 있는 .apply()를 실행해준다고 생각하면 된다.



end




댓글을 달아 주세요