woowacourse-study / 2022-modern-java-in-action

우아한테크코스 4기 모던 자바 인 액션 스터디
10 stars 4 forks source link

컬렉션과 스트림의 차이는 뭘까? #33

Open injoon2019 opened 2 years ago

injoon2019 commented 2 years ago

문제

컬렉션과 스트림의 차이는 뭘까?

선정 배경

스트림에 대한 소개를 읽으면서, 컬렉션이 있는데 왜 굳이 스트림을 만들었을까에 대한 재고.

관련 챕터

chp.4

injoon2019 commented 2 years ago

공통점

연속된 형식의 값을 저장하는 자료구조의 인터페이스를 제공한다.

차이

애초에 컬렉션은 스트림의 재료 중 하나이다.

계산 시기

가장 큰 차이는 언제 계산을 하느냐이다. 컬렉션은 모든 값을 메모리에 저장해놔야 하기 때문에 계산이 되어있다. 그래서 이론적으로 아주 큰 컬렉션은 만들 수 없지만, 스트림은 가능하다 (중간에 filter 등으로 요소가 추려진다는 가정하에).

소모 및 변경

스트림은 데이터를 저장하지 않아서 변경 불가능하다 (스트림에 데이터를 추가하거나 빼는 것) 또한 스트림은 소모성이여서 사용 후 재사용이 불가능하다.

외부 반복과 내부 반복

컬렉션은 사용자가 직접 반복문을 돌리는 외부 반복이다. 스트림은 내부 반복을 사용한다. 선언형과 명령형의 차이인데 이 차이로 인해 가독성이 좋아지고, 병렬성을 얻기도 한다. 물론 내부 반복은 구현이 숨겨져있는 것일 뿐이다.

List<LottoRank> lottoRanks = new ArrayList<>();
for (LottoTicket ticket : tickets) {
    lottoRanks.add(winningTicket.compare(ticket));
}

lottoRanks를 생성하고, lottoRanks값을 하나씩 추가하고 있는 구조인데요. 명령형으로 코드를 작성하면 lottoRanks가 가변변수가 되고, 사이드이펙트가 생길 수 있는 여지가 생기는데요.
이 부분을 선언적으로 작성해보는걸 추천드려요.

public LottoRanks compareResult(WinningTicket winningTicket) {
    return new LottoRanks(tickets.stream()
            .map(winningTicket::judgeRank)
            .collect(Collectors.toList()));
}