네이버 클라우드 캠프/Java

[Java] 스트림 (Stream)

graph-dev 2023. 4. 6. 19:47
728x90

1. 스트림이란?

  • 컬렉션이나 배열의 요소를 반복해서 처리하는 하나의 방식입니다.
  • 컬렉션에 .stream() 메소드가 있어서 컬렉션을 스트림형식으로 변경해서 사용 가능합니다.

 

2. 스트림 선언

컬렉션<타입> list =>
Stream<타입> typeStream = list.stream();

 

3. 스트림의 forEach

  • 람다식을 활용합니다.
  • 컬렉션 요소 하나씩 담는 변수명을 아무거나 지정합니다.
  • 내부에는 처리할 내용이 한 줄이면, 중괄호{} 없이 작성하고, 두 줄 이상이면 중괄호{} 내에 작성합니다.
typeStream.forEach(컬렉션 요소 하나 담은 변수명 -> 
				   {처리할 내용});
  • 내부반복자로, Iterator보다 빠른 처리속도를 가지며, 람다식으로 다양한 작업이 가능합니다.
  • 파이프 라인 혹은 체이닝 기법으로 중간처리와 최종처리를 나누어 수행할 수 있습니다.

 

4. 내부반복자

  • for, Iterator : 컬렉션의 요소를 외부로 꺼내어 사용하는 외부반복자입니다.
  • stream : 요소를 컬렉션 내부로 집어넣어 반복 처리하는 내부반복자입니다.

 

5. 스트림을 연결하여 파이프라인 제작

  • 하나 이상 스트림은 연결이 가능합니다.
  • 마지막에만 최종처리를 하는 스트림을 연결해서 파이프라인을 구성합니다.

 

1) 기존의 스트림

10개의 정수 정보를 리스트에 저장한 것을 스트림으로 만들고, 각 요소에 3을 곱한 값을 출력합니다.

//정수형을 받는 스트림에 저장
Stream<Integer> intStream = intList.stream();
//해당 스트림의 각 요소에 3을 곱한다.
Stream<Integer> newStream = intStream.map(num -> num * 3);
//각 요소를 출력한다.
newStream.forEach(num -> System.out.print(num + ", "));

 

2) 체이닝 기법을 적용한 스트림

intList.stream().map(num -> num * 3).forEach(num -> System.out.print(num + ", "));
  • 체이닝기법
    • 코드가 더욱 깔끔하고 간결해집니다.
    • 메소드의 호출을 연결해서 여러 메소드를 호출할 수 있습니다.
    • 다만 파이프라인 구성할 때, 최종처리가 없으면 에러가 발생합니다.
      ("할꺼면 끝까지 하자!")

6. 자주 사용하는 스트림 메소드

1) stream.forEach()

- stream 내 타입의 요소를 하나씩 접근하면서, 실행코드를 요소의 수만큼 반복해서 실행합니다.

- 반환타입이 void이므로 반환은 불가능합니다.

 

2) stream.map()

- stream에 포함된 타입별 요소를 하나씩 접근해서 실행코드에서 나온 결과값으로 새롭게 스트림을 생성해서 반환합니다.

- 반환이 가능하다!

 

3) stream.filter()

- 필터, 변수에 포함된 요소를 조건 코드에서 true인 요소들만 다시 스트림으로 반환합니다.

 

4) stream.reduce()

Stream<type> stream.reduce((결과값 타입 변수명, 타입 변수명) -> 결과값 처리코드);

- 특이하게도 두가지를 받아서, 스트림을 하나로 결과값 만들어줍니다.

 

7. 스트림 얻는 방법

1) List<T>, Set<T>

- stream(), parallelStream() 메서드를 통해 Stream<T>을 만들 수 있습니다.

 

2) 배열

- 배열의 타입에 스트림을 넣을 수 있습니다.

- 각각의 원시타입별로 배열에 해당하는 스트림이 있습니다.
(IntStream, LongStream, DoubleStream)

Arrays.stream(T[]), Stream.of(T[]) // Stream<T>
Arrays.stream(int[]), IntStream.of(int[]) // int
Arrays.stream(long[]), LongStream.of(long[]) // long
Arrays.stream(double[]), DoubleStream.of(double[]) // double

3) Files 클래스

- 텍스트파일의 데이터를 행별로 스트림으로 생성할 수 있습니다.

Files.list(Path) // Stream<Path>
Files.lines(Path, Charset) // Stream<String>

4) Random 클래스

Random.doubles(...) // DoubleStream
Random.ints(...) // IntStream
Random.longs(...) // LongStream

 

8. 기타 유용한 메소드

1) distinct() : 중복값 제거, equals 활용하여 중복된 객체를 제거합니다.

2) mapToInt(), mapToLong(), mapToDouble() : 각각 Int/Long/DoubleStream으로 변환합니다.

3) as시리즈

- IntStream.asLongStream() : Int를 Long인 스트림으로 변경합니다.

- Int/LongStream.asDoubleStream() : Int 혹은 Long 스트림을 Double 타입 스트림으로 변경합니다.

4) box를 통한 변환

기존 Int/Long/DoubleStream도 .boxed() 메소드를 통해 각 원시타입에 해당하는 스트림으로 변환이 가능합니다.

 

 

'네이버 클라우드 캠프 > Java' 카테고리의 다른 글

[Java] JDBC 이야기  (0) 2023.05.01
[Java] 멀티스레드  (0) 2023.04.06
[Java] 상수의 할당  (0) 2023.03.29
[Java] enum 열거형 정리  (0) 2023.03.29
[Java] Collections  (0) 2023.03.29