[06] Optional 클래스

MIIIN·2023년 5월 5일
0

Modern Java

목록 보기
6/8
post-thumbnail

⚽ Optional 클래스

NullPointerException을 피하려면, 대부분 아래와 같이 null 확인 코드를 넣어서 해결하려고 한다.

public String getCarInsurancename(Person person) {
	if (person != null) {
		Car car = person.getCar();
		if (car != null) {
			Insurance insurance = car.getInsurance();
			if (insurance != null) {
				return insurance.getName();
			}
		}
	}
	return "Unknown";
}

하지만, 이러한 방식은 코드를 난잡하게 하고 쉽게 파악하기에 어렵다.

Java SE 8에서는 java.util.Optional라는 선택형값을 캡슐화하는 클래스를 제공한다.
값이 있으면 Optional 클래스는 값을 감싸며, 값이 없으면 Optional.empty 메서드로 Optional을 반환한다.
Optional.empty는 Optional의 특별한 Singleton Instance를 반환하는 정적 팩토리 메서드이다.


🐏 Optional 적용 패턴

MethodDescription
empty빈 Optional 인스턴스 반환
of값이 존재하면 값을 감싸는 Optional을 반환하고, 값이 null이면 NullPointerException을 발생
ofNullable값이 존재하면 값을 감싸는 Optional을 반환하고, 값이 null이면 빈 Optional을 반환
filter값이 존재하며 Predicate와 일치하면 값을 포함하는 Optional을 반환한다.
값이 없거나 Predicate와 일치하지 않으면 빈 Optional을 반환한다.
ifPresent값이 존재하면 지정된 Consumer를 실행하고, 값이 없으면 아무것도 안함
ifPresentOrElse값이 존재하면 지정된 Consumer를 실행하고, 값이 없으면 Runnable을 실행
isPresent값이 존재하면 true를 반환하고, 값이 없으면 false를 반환
map값이 존재하면 제공된 매핑 함수를 적용
flatMap값이 존재하면 인수로 제공된 함수를 적용한 결과 Optional을 반환하고, 값이 없으면 빈 Optional을 반환
get값이 존재하면 해당 값을 반환하고, 값이 없으면 NoSuchElementExeption을 발생
or값이 존재하면 같은 Optional을 반환하고, 값이 없으면 Supplier에서 만든 Optional을 반환
orElse값이 존재하면 값을 반환하고, 값이 없으면 기본값을 반환
orElseGet값이 존재하면 값을 반환하고, 값이 없으면 Supplier에서 제공하는 값을 반환
orElseThrow값이 존재하면 값을 반환하고, 값이 없응면 Supplier에서 생성한 예외를 발생
stream값이 존재하면 존재하는 값만 포함하는 Stream을 반환하고, 값이 없으면 빈 Stream을 반환

Optional 객체 만들기

  1. 빈 Optional
Optional<Car> optCar = Optional.empty();    
  1. null이 아닌 Optional
Optional<Car> optCar = Optional.of(car);    
  1. null이 허용된 Optional
Optional<Car> optCar = Optional.ofNullable(car);    

Optional 값 추출하고 변환하기

Optional의 map 메서드로 값을 추출하여 변환할 수 있다.

Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName);

Optional 객체 연결

Optional 객체를 연결할 때는 Optional의 flatMap 메서드를 사용한다.

public String getCarInsuranceName(Optional<Person> person) {
	return person.flatMap(Person::getCar)
				.flatMap(Car::getInsurance)
				.map(Insurance::getName)
				.orElse("Unknown");
}

Optional Stream

Java SE 9에서는 Optional에 Stream() 메서드를 추가했다.

public Set<String> getCarInsuranceNames(List<Person> persons) {
	return persons.stream()
				.map(Person::getCar)
				.map(optCar -> optCar.flatMap(Car::getInsurance))
				.map(optIns -> optIns.map(Insurance::getName))
				.flatMap(Optional::stream)
				.collect(toSet());
}

Optional 필터링

Optional의 filter 메서드로 Predicate가 만족하면 값을 반환하고, 그렇지 않으면 빈 Optional 객체를 반환한다.

optInsurance.filter(insurance -> "CambridgeInsurance".equals(insurance.getName()))
			.ifPresent(x -> System.out.println("ok");

profile
백엔드개발자

0개의 댓글