Optional 클래스


Optional, OptionalDouble, OptionalInt, OptionalLong 이 클래스들은 저장하는 값의 타입만 다를 뿐 제공하는 기능은 거의 동일하다. Optional 클래스는 단순히 집계 값만 저장하는 것이 아니라, 집계 값이 존재하지 않을 경우 디폴트 값을 설정할 수도 있고, 집계 값을 처리하는 Consumer도 등록할 수 있다. 다음은 Optional 클래스들이 제공하는 메소드 들이다.



리턴 타입 메소드(매개 변수) 설명
boolean isPresent() 값이 저장되어 있는지 여부
T
double
int
long
orElse(T)
orElse(double)
orElse(int)
orElse(long)
값이 저장되어 있지 않을 경우 디폴트 값 지정
void ifPresent(Consumer)
ifPresent(DoubleConsumer)
ifPresent(IntConsumer)
ifPresent(LongConsumer)
값이 저장되어 있을 경우 Consumer에서 처리



컬렉션의 요소는 동적으로 추가되는 경우가 많다.


List<Integer> list = new ArrayList<>();
double avg = list.stream()
  .mapToInt(Integer :: intValue)
  .average()
  .getAsDouble();

System.out.println("평균 : " + avg);


요소가 없기 때문에 평균값도 있을 수 없다. 그래서 NoSuchElementException 예외가 발생한다. 요소가 없을 경우 예외를 피하는 세가지 방법이 있는데, 첫 번째는 Optional 객체를 얻어 isPresent() 메소드로 평균값 여부를 확인하는 것이다. isPresent() 메소드가 true를 리턴할 때만 getAsDouble() 메소드로 평균값을 얻으면 된다.


OptionalDouble optional = list.stream()
  .mapToInt(Intger :: intValue)
  .average();

if(optional.isPresent()){
  System.out.println("평균 : " + optional.getAsDouble());
} else {
  System.out.println("평균 : 0.0");
}


두 번째 방법은 orElse() 메소드로 디폴트 값을 정해 놓는다. 평균값을 구할 수 없는 경우에는 orElse()의 매개값이 디폴트 값이 된다.


double avg = list.stream()
  .mapToInt(Intger :: intValue)
  .average()
  .orElse(0.0);
System.out.println("평균: " + avg);


세 번째 방법은 ifPresent() 메소드로 평균값이 있을 경우에만 값을 이용하는 람다식을 실행한다.


list.stream()
  .mapToInt(Intger :: intValue)
  .average()
  .ifPresent(a -> System.out.println("평균 : " + a));



import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;


public class OptionalExample{
  public static void main(String[] args){
    List<Integer> list = new ArrayList<>();

    /* // 예외 발생(java.util.NoSuchElementException)
    double avg = list.stream()
      .mapToInt(Integer :: intValue)
      .average()
      .getAsDouble();
    */

   // 방법 1
   OptionalDouble optional = list.stream()
    .mapToInt(Integer :: intValue)
    .average();

  if(optional.isPresent()){
    System.out.println("평균 : " + optional.getAsDouble());
  } else {
    System.out.println("평균 : 0.0");
  }

  // 방법 2
  double avg = list.stream()
    .mapToInt(Intger :: intValue)
    .average()
    .orElse(0.0);
  System.out.println("평균: " + avg);

  // 방법 3
  list.stream()
    .mapToInt(Intger :: intValue)
    .average()
    .ifPresent(a -> System.out.println("평균 : " + a));
}