JAVA/JAVA8

Numeric Streams

최-코드 2024. 8. 24. 15:54

Numeric Stream

  • 기본형 값을 스트림으로 표현하는데에 사용된다. 즉, 각각의 요소는 기본형 타입이다.
  • IntStream, LongStream, DoubleStream 세 가지 타입이 있다. 즉, Stream<>와 같은 형식이 아니다.
  • 일반적인 Stream<>타입과 달리 Numeric Stream을 사용하면 언박싱 과정을 안 거치므로 성능을 최적화할 수 있다. 따라서 숫자와 관련된 작업을 할 때는 Numeric Stream을 사용하는 것이 좋다.

range(), rangeClosed() : IntSteam와 LongStream에서 사용할 수 있는 메소드이다.

 

range() : 시작 값과 종료 값을 받아 스트림을 생성한다. 마지막 값은 포함되지 않는다. 예를 들어, IntStream.range(1,50)은 1부터 49까지의 값을 포함하는 스트림을 반환한다.

rangeClosed() : range()와 같은 역할이지만, 이 때 마지막 값을 포함한다. 예를 들어 IntStream.rangeClosed(1,50)은 1부터 50까지의 값을 포함하는 스트림을 반환한다.

public static void main(String[] args) {
    IntStream range = IntStream.range(1, 5);
    range.forEach(value -> System.out.print(value + " "));
    System.out.println();
    
    IntStream intStream = IntStream.rangeClosed(1, 5);
    intStream.forEach(value -> System.out.print(value + " "));
    System.out.println();
    
    LongStream range1 = LongStream.range(1, 5);
    range1.forEach(value -> System.out.print(value + " "));
    System.out.println();
    
    LongStream longStream = LongStream.rangeClosed(1, 5);
    longStream.forEach(value -> System.out.print(value + " "));
    System.out.println();
    
    DoubleStream doubleStream = LongStream.range(1, 5)
            .asDoubleStream();
    doubleStream.forEach(value -> System.out.print(value+" "));
}
// 출력 : 
// 1 2 3 4 
// 1 2 3 4 5 
// 1 2 3 4 
// 1 2 3 4 5 
// 1.0 2.0 3.0 4.0

cf) DoubleStream에서는 ragne(), rangeClosed() 메소드가 없지만 asDoubleStream()을 통해 IntStream이나 LongStream에서 만든 것을 DoubleStream으로 바꿀 수 있다. 

 

sum(), max(), min(), average() : Numeric Stream에 존재하는 집계함수로, sum()을 뺀 나머지 메소드는 Optional 객체를 반환한다.

public static void main(String[] args) {
    int sum = IntStream.range(1, 50).sum();
    System.out.println(sum);

    OptionalInt max = IntStream.range(1, 50).max();
    System.out.println(max.orElseThrow());

    OptionalInt min = IntStream.range(1, 50).min();
    System.out.println(min.orElseThrow());

    OptionalDouble average = IntStream.range(1, 50).average();
    System.out.println(average.orElseThrow());
}
//출력 : 1225 49 1 25

 

boxed() : 이 메소드를 통해 각각의 기본형을 래퍼 타입으로 감쌀 수 있다. 따라서 boxed() 메소드를 사용하면 Steam<>의 타입을 반환하게 된다. 즉, 박싱의 과정을 거친다.

public static void main(String[] args) {
    List<Integer> boxedIntegers = boxing();
    System.out.println(boxedIntegers);
}

private static List<Integer> boxing() {
    return IntStream.range(1,5)
            .boxed()
            .collect(Collectors.toList());
}

 

 

mapToInt(), mapToLong(), mapToDouble()

  • Steam<>에서 사용하면 언박싱 역할을 한다.
  • numeric stream에서 사용하면 요소의 기본형 타입을 바꾸는 역할을 한다. 
public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3);
        list.stream().mapToInt(Integer::intValue)
                        .forEach(System.out::print);
        System.out.println();

        IntStream.rangeClosed(1, 3)
                .mapToLong(value -> value)
                .forEach(System.out::print);
        System.out.println();

        IntStream.rangeClosed(1, 3)
                .mapToDouble(value -> value)
                .forEach(System.out::print);
}
//출력 :
//123
//123
//1.02.03.0