https://youtu.be/W_kPjiTF9RI?si=qrvIm_TJFy_zidyD
Optional 은 <T> 를 가지고 있는 래퍼 클래스
모든 종류, 어떤 타입인 변수도 가질 수 있음 -> null 도 저장할 수 있음
Optional 이 필요한 이유
- null 을 직접 다루는 것은 위험 -> NullPointerException 이 발생할 수 있음
- 객체 안에 담아 간접적으로 null 을 다루기 위함
- 값의 null 을 체크하기 위해서는 if 문을 사용해야 해서 코드가 지저분해짐 -> 간접적으로 다룰 필요가 있음
Object result = getResult();
이런 메소드가 있는데 Optional 에 담긴 값의 타입으로 Object 가 결정됨
반환값
- null
- 객체
만약 result 로 무엇인가 작업을 하려고 하면 NullpointerException 이 발생
그래서 항상 if 문이 필요
이런 문제를 해결하기 위해 사용하는게 Optional
만약 result 에 null 이 담길 경우에 그 null 을 Optional 객체에 저장
그렇게 되면 result 에는 null 이 담긴 Optional 객체의 주소를 받게 되고
Optional 객체의 값은 null 이지만 객체 자체는 존재하기 때문에 항상 null 오류가 발생하지 않음
-> 간접적으로 다룬다
이러한 객체들을 간접적으로 다루기 위한 것이 Optional
Optional<T> 객체 생성하기
String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optVal2 = Optional.of("abc");
Optional<String> optVal3 = Optional.of(null); // NullPointerException 발생
Optional<String> optVal4 = Optional.ofNullable(null); // 가능
of 는 null 을 받을 수 없지만
ofNullable 은 null 을 받을 수 있음
optVal 은 str 의 주소를 갖고, str 은 "abc" 의 주소를 가짐
Optional 객체 초기화 방법
Optional<String> optVal = null; // 가능은 하지만 바람직하지 않음
Optional<String> optVal2 = Optional.<String>empty();
// 뒤의 <String> 은 생략 가능
Optional 객체의 값 가져오기 - get(), orElse(), orElseGet(), orElseThrow()
Optional<String> optVal = Optional.of("abc");
String str = optVal.get(); // optVal 에 저장된 값을 반환, null 이면 예외 발생
String str2 = optVal.orElse(""); // optVal 에 저장된 값이 null 일 경우 "" 반환
String str3 = optVal.orElseGet(String::new); // 람다식 사용 가능 () -> new String()
String str4 = optVal.orElseThrow(NullPointerException::new); // null 이면 예외 발생
orElseGet 은 람다식 사용 시 Supplier 이기 때문에 입력값 없음, 반환값만 존재
람다식 : 입력값이 없으므로 () -> 로 시작, 새로운 문자열 객체를 반환 new String()
orElseThrow 는 예외 종류를 지정할 수 있음
isPresent() -> Optional 객체의 값이 null 이면 false, 아니면 true 를 반환
if (Optional.ofNullable(str).isPresent()) { // if (str != null)
System.out.println(str);
}
ifPresent() -> null 이 아닐때만 작업 수행, null 이면 아무 일도 안함
Optional.ofNullable(str).ifPresent(System.out::println);
Optional 객체의 값이 null 이 아니면, 출력문을 실행
System.out::println -> 람다식의 출력문
실습해보기
Optional<String> opt = Optional.empty();
System.out.println(opt); // Optional.empty 출력
System.out.println(opt.get()); // NoSuchElementException 오류 발생
Optional 객체를 get() 할 시 예외 처리하기
Optional<String> opt = Optional.empty();
String str = "";
try {
str = opt.get();
} catch (Exception e) {
str = "";
}
이렇게 만들 수 있지만..
orElse() 를 사용하면 더 편하게 할 수 있음
Optional<String> opt = Optional.empty();
str = opt.orElse("empty");
System.out.println(str); // empty 문자열 출력
orElseGet() 을 사용하여 람다식 사용해보기
Optional<String> opt = Optional.empty();
str = opt.orElseGet(() -> new String());
str = opt.orElseGet(String::new); // 위와 같은 역할을 함
str = opt.orElseGet(() -> "empty");
System.out.println(str); // empty 출력
OptionalInt, OptionalLong, OptionalDouble
기본형 값을 감싸는 래퍼클래스
Optional<T> 는 String, Integer 등 참조형을 사용하였지만
OptinalInt 는 기본형인 int 을 사용
OptionalInt 클래스에는 value 와 isPresent 변수가 있음
빈 OptionalInt 를 생성하여도 value 값은 0 으로 초기화
그러면 0 을 저장한 것인지, 값이 없어 0 이 출력되는 것인지 확인하는 방법 -> isPresent() 사용
OptionalInt optInt = OptionalInt.of(0);
OptionalInt optInt2 = OptionalInt.empty();
System.out.println(optInt.isPresent()); // true
System.out.println(optInt2.isPresent()); // false
System.out.println(optInt.equals(optInt2)); // false
value 는 같지만 저장과 초기화된 값은 다르게 출력
전체 실습
Optional 만들고 출력해보기
map 은 값을 변환해주는 역할
Optional<String> optStr = Optional.of("apple");
Optional<Integer> optInt = optStr.map(s -> s.length());
System.out.println("optStr : " + optStr.get()); // optStr : apple
System.out.println("optInt : " + optInt.get()); // optInt : 5
Optional 객체 만들고 값 변환하고, 조건 걸고 람다식 쓰면서 다 해보기
int num = Optional.of("123").filter(str -> str.length() > 0)
.map(str -> Integer.valueOf(str)).get();
int num2 = Optional.of("").filter(str -> str.length() > 0)
.map(str -> Integer.parseInt(str)).orElse(-1);
// filter 를 통과하지 못해 Optional 값이 null 로 변함
System.out.println("num : " + num); // num : 123
System.out.println("num2 : " + num2); // num2 : -1
ifPresent() 사용해보기
Optional.of("456").map(i -> Integer.valueOf(i))
.ifPresent(i -> System.out.printf("result : %d", i));
// result : 456
'JAVA' 카테고리의 다른 글
String, StringBuffer, StringBuilder (0) | 2024.08.05 |
---|---|
240111 홈페이지 만들기 (2) | 2024.01.11 |
240103 Java (0) | 2024.01.03 |
231227 Java (0) | 2023.12.27 |
231226 Java (0) | 2023.12.26 |