스트림(Stream)

  • by

  • 물이 흐르도록 물체를 연속 척으로 처리하는 기능
  • 요소가 하나씩 흐르면서 처리된다는 의미
  • 람다식을 이용

스트림의 특징

  1. 처리 속도가 빠르고, 병렬 처리에 효율적(=내부 이터레이터의 특징)
  2. 람다 식으로 다양한 요소 처리를 정의 가능
  3. 중간 처리와 최종 처리를 실시하기 위한 파이프라인 형성이 가능


내부 반복자

  • 내부 반복자: 요소 처리 방식을 컬렉션에 주입하여 내부에서 요소를 반복합니다.

  • 외부 반복자: 컬렉션의 요소를 컬렉션 내에서 반복 꺼내 처리
  • 스트림을 이용하면 병령 처리가 가능하며, 이것에 의해 CPU 처리 효율성의 증대를 도모할 수 있다.


    – 처리하는 요소가 적은 경우는, 멀티 thread보다 싱글 thread가 효율적입니다.


    – 멀티스레딩과 같은 병렬 처리는 처리할 요소가 많을 때 더 효율적입니다.


중간 처리 및 최종 처리

  • 스트림을 복수 접속해 사용할 수도 있습니다.

  • 중간 스트림: 최종 처리할 요소를 필터링(필터링), 변환(매핑), 정렬하는 등의 작업 수행
  • 최종처리 : 중간처리를 통해 정제된 요소를 반복하여 집계(카운트, 종합평균 등) 작업을 실시

데이터(컬렉션, 배열) 중간 처리 최종 처리 결과
오리지널 스트림 중간 스트림 1 중간 스트림 2 집계 처리
한국인 남자 군필자 남은 인원수 집계 한국인 중 군대대한 남자 수
Student(학생 오브젝트) score(스코어 필드) 평균 계산 학생들의 평균 점수

//Student 스트림 – 원본 스트림
스트림<Student> studentStream = list.stream();
//score 스트림 – 중간 스트림
IntStream scoreStream = studentStream.mapToInt (student > student.getScore() ); //Student 객체를 getScore() 메서드의 반환값에 매핑
// 평균 계산 – 최종 처리
double avg = scoreStream.average().getAsDouble();

  • 대부분의 map으로 시작하는 메소드는, 어느 오브젝트의 형태를 변경하는 메소드입니다.


    – 위의 예에서는 평균 점수를 계산하기 위해 mapToInt() 메서드를 사용하여 Student 개체를 int 형식의 점수 값에 매핑했습니다.


리소스에서 스트림 얻기

패키지 상위 인터페이스 자식 인터페이스 데이터 유형
java.util.Stream BaseStrem 스트림 참조 유형(객체)
IntStream int 형
LongStream long 타입
DoubleStream double 타입(실수)

스트림 구현 오브젝트를 취득하는 메소드

클래스/인터페이스 방법 타겟 리소스 비고
Collection(java.util) static Stream stream() 목록 컬렉션
static 스트림 parallelStream() Set 컬렉션 병렬 스트림
Arrays static 스트림 stream(T( )) 배열
static IntStream stream(int( )) 배열
static LongStream stream(long( )) 배열
static DoubleStream stream(double( )) 배열
스트림 static 스트림 of(T( )) 배열
IntStream static IntStream of(int( )) 배열
static IntStream range(int, int) 수치 범위 마지막 숫자를 포함하지 않음
static IntStream rangeClosed(int, int) 수치 범위 마지막 숫자 포함
LongStream static LongStream of(long( )) 배열
static LongStream range(long, long) 수치 범위 마지막 숫자를 포함하지 않음
static LongStream rangeClosed(long, long) 수치 범위 마지막 숫자 포함
DoubleStream static DoubleStream of(double( )) 배열
Files static 스트림 list(Path) 디렉토리
static 스트림 lines(Path, Charset) 텍스트 파일
무작위 static IntStream ints(…) 난수
static LongStream longs(…) 난수
static DoubleStream doubles(…) 난수


컬렉션에서 스트림 가져오기

  • java.util.Collection 인터페이스의 stream() 및 parallelStream() 메소드의 사용
    – parallelStream() 메소드는 병렬 처리시에 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
공개 수업 제품 {
비공개 int pno;
비공개 문자열 이름;
비공개 문자열 company;
비공개 int price;
공개 Product(int pno, 문자열 이름, 문자열 회사, int 가격) {
this.pno = pno;
this.name = 이름;
this.company = company;
this.price = price;
}
공개 int getPno() { return pno;}
공개 문자열 getName() { return name;}
공개 문자열 getCompany() { return company; }
공개 int getPrice() { return price;}
@Override
공개 문자열 toString() {
return 새로운 StringBuilder()
.append (“{“)
.append (“pno:” + pno + “,”)
.append (“name:” + 이름 + “,”)
.append (“company:” + company + “,”)
.append (“price:” + 가격)
.append (“}”)
.toString();
}
}

//List 컬렉션 만들기
리스트<제품> list = 새로운 ArrayList<>();
for(int i=1;i<=5;i++) {
Product product = 새로운 Product(1, 「상품」+i, “멋진 회사”(int)(10000*Math.random()));
list.add(product);
}
// 객체 스트림 얻기
스트림<제품> stream = list.stream();
stream.forEach(p > 시스템.out.println(p));


실행 결과


배열에서 스트림을 가져옵니다.

  • java.util.Arrrays 클래스의 stream() 메소드 사용

// 참조형(객체) 배열
문자열() strArray = {‘홍길동’, ‘김길동’, ‘남길동’};
스트림<문자열> strStream = Arrays.stream(strArray);
strStream.forEach(item > 시스템.out.인쇄(item + “,”));
시스템.out.println();
// 기본형(int, long, double) 배열
int() intArray = { 1, 2, 3, 4, 5 };
IntStream intStream = Arrays.stream(intArray);
intStream.forEach (item > 시스템.out.인쇄(item + “,”));
시스템.out.println();


실행 결과


숫자 범위에서 스트림 가져오기

  • IntStream, LongStream range() 및 rangeClosed() 메서드 사용

공개 static int sum;
공개 static void main(문자열() args) {
IntStream stream = IntStream.range (1, 100); // 1에서 100 미만의 정수 스트림 생성
stream.forEach (a > sum += a); //1에서 100까지의 합계
시스템.out.println(「종합:」 + sum);
}


실행 결과


파일에서 스트림 가져오기

  • java.nio.file.Files의 lines() 메소드를 사용하여 텍스트 파일의 행 단위 스트림을 검색할 수 있습니다.


    – 파일 경로(Path)로 인코딩하는 문자 세트(Charset) 필요

data.txt
0.00MB


1
2
3
4
5
6
7
8
9
10
11
12
// 해당 소스 파일과 동일한 디렉토리(패키지)에 있는 data.txt 파일의 내용을 콘솔에 출력하는 프로그램
try {
Path path = Paths.get (StreamExample.수업.getResource (“data.txt”).toURI()); //data.txt 파일 경로의 Path 객체 생성
스트림<문자열> stream = Files.lines(path, Charset.defaultCharset()); // 해당 경로의 파일 내용을 기본 문자 집합으로 인코딩하여 스트림을 생성합니다.

stream.forEach (line > 시스템.out.println(라인));
stream.close();
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}


실행 결과


URI 및 URL

  • URI(Uniform Resource Identifier): 특정 리소스를 식별하는 통합 리소스 식별자
    – 웹 기술에서 사용되는 논리/물리 리소스를 식별하는 고유 문자열 시퀀스
  • URL(Uniform Resource Locator): 특정 리소스의 위치를 ​​가리키는 문자열
    – 컴퓨터 네트워크의 리소스가 어디에 있는지 알려주는 약관
    – URI의 서브 세트
    – 자원의 위치 정보도 고유한 값이므로 URL을 URI로 변환하는 메소드가 있습니다.

    (URI toURI ()) f