Java

Java Stream (5) 기본 자료형 스트림

감동이중요해 2020. 7. 22. 01:03

기본 자료형 스트림

이번 포스트에서도 아래의 예시 데이터를 사용한다.

@Getter
@AllArgsConstructor
@EqualsAndHashCode
public class City {
    private String name;
    private double area;
    private int population;
    private String areaCode;
}

List<City> cities = Arrays.asList(
        new City("Seoul", 605.2, 9720846, "02"),
        new City("Incheon", 1063.3, 2947217, "032"),
        new City("Ulsan", 1062, 1142190, "052"),
        new City("Daegu", 883.5, 2427954, "053"),
        new City("Gwangju", 501.1, 1455048, "062"),
        new City("Busan", 770.1, 3404423, "051")
);

일반 스트림을 사용하여 cities의 모든 population을 구해보면 아래와 같다.

int sum = cities.stream()
        .map(City::getPopulation)
        .reduce(0, Integer::sum);

코드가 작동하는 데엔 문제는 없지만 내부적으로 박싱/언박싱을 수행하므로 성능이 크게 저하된다.

개념

스트림은 IntStream , DoubleStream , LongStream 세 가지가 존재한다.

다만 일반 스트림에 비해 특별하게 추가된 기능은 없고 박싱/언박싱 관련 효율성의 장점을 갖는다.

int sum = cities.stream()
        .mapToInt(City::getPopulation) // IntStream으로 변환
        .sum();

변환 방법

Stream 클래스에 포함된 세 가지 메소드를 사용한다.

  1. Stream::mapToIntIntStream 반환
  2. Stream::mapToDoubleDoubleStream 반환
  3. Stream::mapToLongLongStream 반환

기본형 타입 스트림으로 바꾸었으니 반대로 일반형인 Stream<T> 으로도 다시 변환할 수 있다.

  1. IntStream::boxed
  2. DoubleStream::boxed
  3. LongStream::boxed

메소드 명은 모두 boxed로 같다.

Optional 활용

최대값 등 Nullable 가능성이 있는 최종 연산은 Optional<T> 를 반환한다.

Optional<Integer> max = cities.stream()
        .map(City::getPopulation)
        .reduce(Integer::max);

Optional<T> 는 레퍼런스 타입에서만 활용할 수 있다.

그러나 기본형 타입은 null이 따로 존재하지 않는다.

int형 계산을 끝마친 결과가 0이라고 가정한다.

int의 기본값은 0인데, 결과도 0이라는 것이 계산을 안 했다는 말은 아니다.

이런 애매한 상황을 위해 기본형 타입에서도 사용할 수 있는 optional 클래스가 존재한다.

  1. OptionalInt
  2. OptionalDouble
  3. OptionalLong
OptionalInt max = cities.stream()
        .mapToInt(City::getPopulation)
        .max();

기본형 Optional도 Optional<T> 와 마찬가지로 .isPresent(), .orElse() 등의 메소드를 갖는다.