[자바] 스트림(Stream)

손경이·2023년 11월 7일
0

자바

목록 보기
11/17

2023.11.07 [테킷 백엔드 장희성 강사님 강의]

스트림(Stream)

특징

  • 일종의 흐름이다.
  • 스트림의 경우 변환하는 공장이다.
  • 데이터를 변환하기에는 좋은데 데이터를 사용하기에는 불편하다.
  • .filter() -> .map() -> .collect() 거의 이런 흐름으로 사용한다.
.filter() - 필터링
.map() - 매핑, 1:1 변환
.collect() - 스트림 데이터 변환이 끝나고 데이터를 사용할 때
.forEach - 종단함수, 스트림이 끝난다. 1개 요소씩 실행된다. / .collect()도 종단함수

좋은 점

  • 스트림을 쓰면 소스코드가 간결해져서 좋다.
- 스트림은 자바8부터 나왔다. 하지만 많이 안 쓰는데 그 이유가 반복문이 익숙해서 잘 안 쓴다.
- 익숙해지는 방법 반복문 복사해서 챗지피티한테가서 `절차식 코드를 함수형으로, 함수형 코드를 절차식으로 바꿔달라고 ChatGPT에 부탁하자`

예시

1부터 10까지 출력하기, IntStream, forEach

  • 아래에 스트림을 쓰는 과정을 살펴보면 재밌다.
  • 차근차근 하나씩 살펴보면 이해가 될거다. 인텔리제이에서 디버그모드로 스트림의 흐름을 알 수 있다.
    - 나눠서 볼 수 있고 한눈에 볼 수 있다.
package com.ll.date20231107;

import java.util.stream.IntStream;

public class IntStreamStudy {
    public static void main(String[] args) {
        System.out.println("== v1 ==");
        for (int i = 0; i <= 10; i++) {
            System.out.println(i);
        }

        System.out.println("== v2 ==");
        // 스트림화하면 소스코드가 좀 더 보기가 좋아지고
        // 만들기도 쉬워진다. 짧아진다.
        // rangeClosed(1, 10) : 1~10까지 10개 요소 / range(1, 10) : 1~9까지
        // .forEach : 종단함수, 스트림이 끝난다. 1개 요소씩 실행된다. / .collect()의 일종이다.
        IntStream.rangeClosed(1, 10)
                .forEach((int i) -> {
                    System.out.println(i);
                }); // 람다표현식

        System.out.println("== v3 ==");
        IntStream.rangeClosed(1, 10)
                .forEach((i) -> {
                    System.out.println(i);
                });

        System.out.println("== v4 =="); // i 괄호 생략 가능
        IntStream.rangeClosed(1, 10)
                .forEach(i -> {
                    System.out.println(i);
                });

        System.out.println("== v5 ==");
        IntStream.rangeClosed(1, 10)
                .forEach(i -> System.out.println(i));

        System.out.println("== v6-1 == 1부터 10까지 출력");
        IntStream.rangeClosed(1, 10)
                .forEach(System.out::println);

        System.out.println("== v6-2 == 2만 출력");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i==2)
                .forEach(System.out::println);

        System.out.println("== v6-2-1 == 2의 배수만 출력");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i % 2 == 0)
                .forEach(System.out::println);

        // map 들어오는 녀석을 변환
        System.out.println("== v6-3 == map 들어오는 녀석을 변환");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i % 2 == 0)
                .map(i -> i * 10)
                .forEach(System.out::println);

        // mapToObj 들어오는 타입 일반타입 IntStream, 나가는 객체타입 Stream<String>
        System.out.println("== v6-4 == mapToObj 들어오는 타입(IntStream)와 나가는 타입(Stream<String>) 다를 때");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i % 2 == 0)
                .map(i -> i * 10)
                .mapToObj(i -> i + "점")
                .forEach(System.out::println);

        // 기본적으로 map을 쓴다
        // mapTo타입은 일반 타입에서 객체타입으로 바뀔때 쓰면 된다.
        System.out.println("== v6-5 ==");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i % 2 == 0)
                .map(i -> i * 10)
                .mapToObj(i -> i + "점")
                .map(s -> "[" + s + "]")
                .forEach(System.out::println);

        // 스타일 따라 다름 이렇게 합쳐서 쓰시는 분들도 있다.
        System.out.println("== v6-6 ==");
        IntStream.rangeClosed(1, 10)
                .filter(i -> i % 2 == 0)
                .mapToObj(i -> "[" + i * 10 + "점]")
                .forEach(System.out::println);
    }
}

0개의 댓글