본문 바로가기

JAVA

JAVA Stream 사용법

Project를 진행하던 중, stream에 대한 정리가 필요하다 생각되어, 정리한다.😀

 

Stream


자바8부터 추가된 기능으로, " 컬렉션, 배열" 등의 저장 요소를 하나씩 참조하며 함수형 인터페이스 ( 람다식 )를 적용하며

반복적으로 처리할 수 있도록 해주는 기능이다.

 

 

List<String> names = Arrays.asList("jeong", "pro", "jdk", "java");
// 기존의 코딩 방식
long count = 0;
for (String name : names) {
    if (name.contains("o")) {
        count++;
    }
}
System.out.println("Count : " + count); // 2
 
// 스트림 이용한 방식
count = 0;
count = names.stream().filter(x -> x.contains("o")).count();
System.out.println("Count : " + count); // 2


출처: https://jeong-pro.tistory.com/165 [기본기를 쌓는 정아마추어 코딩블로그]

위 코드에서 아랫 부분이 Stream을 활용한 부분이다. for문으로 이루어져있던 코드를 단 한줄로 바꾸어버렸다.

불필요한 코딩을 걷어낼 수 있고, 직관적이기 때문에 가독성을 좋게 한다.

 

 

 

 

구조


스트림의 구조는 크게 3가지로 구성된다.

1. 스트림 생성

2. 중개 연산

3. 최종 연산

 

.스트림 생성().중개 연산().최종 연산()

이런 식으로 진행된다.

 

 

중개 연산


Filter

List<String> names = Arrays.asList("aa","bb","cc","dd");
Stream<String> str = names.stream().filter(x -> x.contains("b"));

Map

List<String> names = Arrays.asList("aa","bb","cc","dd");
names.parallelStream()
	.map(x->x.concat("s"))
    .forEach(x->System.out.println(x));
// aas, bbs, ccs, dds

MapToInt, MapToLong, MapToDouble

해당 타입의 스트림으로 바꾸어준다. 

 

 

최종 연산


 

count  , min  , sum , average 

개수, 최솟값, 최댓값 등등을 구해준다.

 

reduce 

List<Integer> ages = new ArrayList<>();
ages.add(1);
ages.add(2);
ages.add(3);
ages.add(4);

System.out.println(ages.stream().reduce((a,b) -> a+b).get());

 

누적해서, 연산을 수행한다. 위의 예에서는 값을 더해나가서 , 결국은 1+2+3+4 = 10 의 결과값을 출력한다.

 

collect

스트림의 값을 모아주는 역할을 한다. toMap, toSet 등으로 해당 스트림을 다시 컬렉션으로 바꿔준다.

 

 

 

 

🖐 주의 사항


 

 

재사용  불가능

Stream을 통해서 뽑아낸 값에 대해서 다시 Stream을 이용하면 에러가 난다.

 

병렬 스트림은 여러 쓰레드가 작업한다.

names.parallelStream().filter(x -> x.contains("o")).count();

출처: https://jeong-pro.tistory.com/165 [기본기를 쌓는 정아마추어 코딩블로그]

parallelStream()은 병렬 스트림을 만들 수 있는 함수이다.

이렇게 하면, 여러 쓰레드가 스트림에서 요소를 필터링하고 나온 요소 수를 계산하고 쓰레드끼리 다시 한 번 각자 계산한

count값들을 더해서 리턴해준다.

 

병렬스트림이 성능면에서 유리해보일 수는 있지만, 사용하는 쓰레드가 많거나 스트림의 요소 수가 많지 않다면

오히려 쓰레드를 사용하는 것이 오버헤드가 더 클 수 있다.

 

 

중개 연산은 미리하지 않는다.

Stream<String> a = names.stream().filter(x -> x.contains("o")).map(x-> x.concat("s"));
a.forEach(x -> System.out.println(x));

출처: https://jeong-pro.tistory.com/165 [기본기를 쌓는 정아마추어 코딩블로그]

forEach와 같은 최종 연산이 적용될 때, 중개 연산도 실행된다. ( 즉, filter와 map의 경우 forEach가 실행될 때 실행된다. )

이 때 얻는 이점은, 미리 계산해서 두 번 순회하는 일이 없도록 한다는 것이다.

 

 

 

 

 

 

 

 

 

 

 

https://jeong-pro.tistory.com/165

 

자바 스트림(Stream) API 정리, 스트림을 이용한 가독성 좋은 코드 만들기(feat. 자바 람다, 함수형 프

Java Stream 자바 공부를 하면서 Stream이 무엇인지, 어떻게 사용되고 있는지 인지는 하고 있었으나 실제 코드로 타이핑해보지 않았다. 그러던 중 이번에 가볍게 API 훑어보는 식으로 공부를 하면서

jeong-pro.tistory.com