본문 바로가기
IT 정보/Java

[Java] 스트림 (Stream) (스트림 생성)

by 동그리가조아 2022. 5. 28.
반응형

스트림(Stream)이란?

스트림은 배열, 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 도와주는 반복자!! 


※사용 시 주의점
  - read - only
  - 스트림은 1회용이므로, 한 번 사용하면 닫힌다. 필요하다면 새로 생성해야 한다.
  - 스트림은 원본 데이터를 변경하지 않는다. 
  - 외부반복 컬렉션과 달리 내부반복을 통해 수행한다. 
  - parallelaStream() 메서드를 통해 손쉬운 병렬처리를 지원한다. 
  - 스트림 연산은 filter-map 기반의 API를 사용하여 지연연산을 통해 성능을 최적화한다. 


 

파이프 라인이란?

스트림(Stream)은 중간연산과 최종 연산을 파이프 라인으로 해결한다. 파이프 라인은 여러 개의 스트림으로 연결되어 있는 구조를 말하는데, 최종 연산을 제외하고 나머지는 모두 중간 연산 스트림이다. 

 

작동 방식?

최종 연산이 시작되면 컬렉션 요소가 하나씩 중간 스트림에서 연산되어 최종 연산으로 오게된다. 중간 메서드들은 연산된 스트림을 리턴 시켜 연속 작업을 진행할 수 있다. 

  1. 스트림의 생성
  2. 스트림의 중간 연산 (스트림의 변환)
  3. 스트림의 최종 연산 (스트림의 사용)

 

Stream 생성

Collection 인터페이스에는 stream() 정의되어 있어, 스트림을 생성할 수 있다. Stream을 사용하면 해당 Collection의 객체를 소스로 하는 Stream을 반환한다. 

  1. 컬렉션 
  2. 배열 
  3. 가변 매개변수
  4. 지정된 범위의 연속된 정수
  5. 특정 타입의 난수들 
  6. 람다 표현식
  7. 빈 스트림 생성

 

컬렉션 스트림 생성 

모든 Collection의 최고 조상은 Collection 인터페이스는 Stream()메서드가 정의되어 있다. ( List, Set 컬렉션에서 가능 )

ArrayList<Integer> list = new ArrayList<Integer>();   // List 생성
 
list.add(4);  // List에 값 입력
list.add(2);
list.add(3);
list.add(1);

Stream<Integer> stream = list.stream();  // List 를 Stream 배열에 입력

stream.forEach(System.out::println);  // 스트림을 순회하며, 출력 // 

4
3
2
1

 

배열 스트림 생성

Arrays 클래스에 다양한 형태의 Stream() 메서드가 클래스 메소드로정의되어 있다. 별도로 기본 타입은  java.util.stream 패키지의 IntStream, LongStream, DoubleStream 인터페이스로 제공하고, Arrays 클래스에서 stream() 메소드는 배열의 특정부분만도 스트림 생성이 가능하다.

String[] arr = new String[]{"a", "b", "c", "d"};
 
// 배열에서 스트림 생성
Stream<String> stream1 = Arrays.stream(arr);
stream1.forEach(e -> System.out.print(e + " "));
System.out.println();

//
a
b
c
d
 
// 배열의 특정 부분만을 이용한 스트림 생성
Stream<String> stream2 = Arrays.stream(arr, 1, 3);  // 마지막 인덱스 미포함
stream2.forEach(e -> System.out.print(e + " "));

// 
b
c
  //전달받은 배열또는 인자를 리스트로 
List<String> list = Arrays.asList("a", "b", "c");
  // List로부터 스트림을 생성
Stream<String> listStream = list.stream();

  //스트림의 모든 요소를 출력
listStream.forEach(System.out::prinln);

 

가변 매개변수 스트림 생성

of() 메소드를 사용하여 매개변수를 전달받아 스트림 생성 가능

Stream.of 메서드 
  Stream <String> stream = Stream.of("a", "b", "c"); // 가변 인자
  Stream <String> stream = Stream.of(new String [] {"a", "b", "c"});

Arrays.stream 메서드
  Stream <String> stream = Arrays.stream(new String [] {"a", "b", "c"});
  Stream <String> stream = Arrays.stream(new String [] {"a", "b", "c"}, 0, 3); //end 범위 미포함

 

특정 타입의 난수들

 : range() 메소드를 사용, 연속된 정수를 스트림으로 생성할 때 사용 (IntStram 등등)

IntStream stream = new Random().ints(4);
stream.forEach(System.out::println);

//
12302130
21301203
12301230
23101230

 

람다 표현식 ( 추가 공부 필요 ) 

 : 짝수만을 이용해 이루어진 무한 스트림 생성하는 예제

IntStream stream = Stream.iterate(2, n -> n + 2);  // 2, 4, 6, 8, 10, ...

 

 

빈 스트림

 : 아무 요소도 가지지 않는 빈 스트림은 empty() 메소드를 사용하여 생성할 수 있습니다

// 빈 스트림 생성
Stream<Object> stream = Stream.empty();

System.out.println(stream.count()); 

// 스트림의 요소의 총 개수를 출력함.

 

 

최종 스트림 사용 예시 

Stream .of (1,2,3,4) // 데이터 소스 ( Data source ) -- 스트림 생성
            .filter(n -> n %2 != 0 ) // 중간 연산
            .map(n->n*2) // 중간 연산
            .forEach ( n-> System.out.println(n)); // 최종 연산

 

반응형