Java Stream이란 특징부터 사용하는 이유까지 모두 알려드립니다.
빠르게 변화하는 시장 환경에서 기업과 조직의 핵심 자산인 데이터. 유동성이 높은 시장에 효과적으로 적응하고 비용 및 자원을 효율적으로 관리하기 위해 데이터 처리의 중요성이 점점 부각되고 있는데요. 데이터가 중요해 질수록 강력한 데이터 처리 기능을 선보이며 데이터 처리 효율을 높여주는 ‘Java Stream’의 수요도 함께 높아지고 있습니다.
시스템의 로그 데이터나 IOT의 사물인터넷 데이터 또는, 쉴 새 없이 쏟아지는 이미지, 동영상 같은 데이터가 기하급수적으로 증가하는 가운데, 이를 빠르게 처리하기 위해 기업에선 데이터를 병렬 방식으로 처리하며 업무 효율을 높이고 있는데요.
Java 환경에서 데이터의 병렬처리를 통해 처리 속도를 올리며 데이터 분석, 가공을 위해 필수적인 도구로 꼽히고 있는 ‘Java Stream’에 대해 대한민국 No.1 IT 인재 매칭 플랫폼 이랜서에서 자세하게 알려드리겠습니다.
Java Stream이란
영어의 ‘Stream’이란 사전적 의미로 ‘시냇물’과 같은 의미로 쓰이며, 물의 흐름을 의미하는 용어입니다. 캠브릿지 사전에서는 ‘연속적인 사물이나 사람의 흐름’이라고 정의합니다. 개발에서는 어떤 의미일까요? 개발에서 Stream은 물의 흐름이 아닌 ‘일련의 데이터의 흐름’을 의미한다고 볼 수 있습니다.
위키피디아에서는 이러한 Stream을 ‘시간상에 나타나는 일련의 데이터 요소’라고 정의합니다. 즉, 데이터의 집합이라는 의미보다는 ‘연속적인 데이터의 흐름’ 이라는 점에 초점을 맞춘 용어입니다.
Java의 Stream API는 ‘일련의 데이터의 흐름’을 표준화된 방법으로 쉽게 처리할 수 있도록 지원하는 ‘클래스의 집합(패키지)’입니다. 오라클 공식 문서에서는 Stream 패키지를 ‘요소들의 Stream에 함수형 연산(람다함수를 통한 연산)을 지원하는 클래스’라고 정의하고 있습니다.
즉, Java의 Stream을 이용하면 일련의 데이터를 함수형 연산을 통해 표준화된 방법으로 쉽게 가공, 처리할 수 있습니다. Java Stream은 대량의 데이터를 표준화된 방식으로 처리하기 위한 용도로 만들어졌기 때문인데요.
Java Stream API는 이러한 작업을 간편하게 수행할 수 있도록 다양한 기능을 제공하며, 병렬 처리를 통해 처리 속도를 높일 수 있습니다. 이러한 이유로 Java Stream은 데이터 처리 및 분석 작업에 필수적인 도구로 자리 잡고 있는데요. Java Stream을 사용하는 이유에 대해 알아보겠습니다.
Java Stream을 사용하는 이유
Java Stream을 사용하기 전에는 데이터를 컬렉션(Collection)으로 처리했습니다. 코딩이 길고 가독성이 불편하여 작업할 때 애로 사항이 많았는데요. 그렇다면 기존 Java의 컬렉션 처리 방식에 비해 Java Stream을 사용할 때의 장점은 어떻게 될까요?
가독성 향상
프로그램을 코딩할 때, 어떻게 할지를 하나하나 기술하는 ‘명령형’ 방식으로 코딩하지 않고, 무엇을 하고싶다는 ‘선언적’으로 코딩이 가능합니다. 또한, 연속적으로 필터링, 매핑, 정렬을 ‘체이닝’하여 표현할 수 있습니다.
사람의 이름으로 구성된 ArrayList 데이터에서, 이름이 ‘A’로 시작하고 글자수가 4개 이상인 이름을 찾아야한다고 생각해보겠습니다. 기존의 반복문으로 사용하게되면 코드가 아래와 같이 길어지고 머를 하려고 하는 것인지 의미가 명확하지 않습니다. 그래서 아래와 같이 주석을 달아야 어떤 작업을 하는지 알수 있습니다.
[반복문으로 처리하는 기존방식]
반면 Stream을 사용하게 되면 코딩이 훨씬 간결해지고 명료해져서 소스코드의 가독성이 좋아집니다.
[Java Stream API를 사용한 방식 ]
유지보수성 향상
Java Stream을 사용하기 전에는 복잡한 반복 문과 조건문으로 인해 코드가 지나치게 길고 복잡했습니다. 이로 인해 코드의 가독성이 저하되고 유지보수가 어려웠는데요. 하지만 Java Stream을 사용하면 간결하고 명확한 코드로 데이터를 처리할 수 있어서 코드의 가독성과 유지보수성이 향상됩니다.
코드에 주석을 달지 않더라도 코드의 의도를 파악하기 쉬워지고, 변경이 필요한 부분을 쉽게 수정할 수 있습니다. 덕분에 Java Stream을 사용하면 코드를 직접 개발한 개발자가 아니어도 코드의 구조를 한눈에 알아보기 쉬워 유지보수 및 인수인계 시에도 어려움 없이 작업을 할 수 있습니다.
병렬처리 지원
Stream에서 지원하는 병렬처리는 데이터의 흐름을 나누어서 멀티 스레드로 병렬로 처리하고 처리 후에 합치는 과정을 통해 대량의 데이터를 빠르고 쉽게 처리할 수 있다는 장점이 있습니다.
데이터를 병렬 처리 지원은, 멀티 스레드를 이용하기 때문에 데이터를 효율적으로 처리할 수 있는데요. 이는 대용량 데이터를 효율적으로 처리하기 위해 필수적인 기능이며, Java Stream API는 간단하게 parallel() 또는 parallelStream()이라는 연산을 추가하는 것만으로 병렬처리가 가능합니다.
이해를 돕기 위해 대용량 로그 파일의 분석이나 대규모 데이터베이스의 쿼리 처리 등을 예로 들 수 있는데요. 로그 파일에서 특정 이벤트의 발생 빈도를 분석하거나, 대규모 데이터베이스에서 특정 기간 동안의 거래 내역을 집계하는 경우가 있습니다.
이러한 작업은 많은 양의 데이터를 처리해야 하므로, 병렬 처리를 통해 처리 시간을 단축할 수 있는데요. Java Stream이 어떻게 대규모 데이터를 효율적으로 처리하는지 구조와 특징을 보여드리며 설명드리겠습니다.
Java Stream의 처리 구조와 처리 특징
데이터를 처리하기 위해서는, 일단 데이터를 생성하고, 생성된 데이터를 가공하여 필요한 형태로 변환한 다음, 최종적으로 결과를 소비해야 합니다.
데이터를 처리하기 위한 API이므로, 데이터의 각각의 단계별로 처리할 수 있도록 구성되어 있는데요. 정리하면, Java Stream은 ‘생성 -> 가공 -> 소비’의 구조로 구성되어 있습니다.
Stream 생성
생성은 데이터의 컬렉션(집합)을 Stream으로 변환하는 과정으로 stream을 만들어 내는 것을 의미합니다. Stream API를 사용하여 가공하기 위해서 최초 1번 수행되어야 합니다. 생성 단계에서는 특징은 모든 데이터가 한꺼번에 메모리에 로드되지 않고 필요할 때만 로드됩니다. 이는 대량의 데이터 셋에서 메모리 사용량을 최적화하고, 불필요한 데이터를 로드하지 않아도 되어 효율적입니다
가공(중간 연산)
가공은 소스의 데이터 집합을 원하는 형태로 가공하는 것으로 중간처리를 의미합니다. 필터(filter), 변형(map), 정렬(sort) 등의 가공을 말하는 것으로, Java Stream API가 데이터를 여러 가지로 가공을 하기 위한 목적이므로 중간처리 과정을 통해 데이터에 대한 다양한 가공을 수행할 수 있습니다. 중간 연산의 입력값은 Stream이며, 결과물도 Stream입니다. 결과물이 Stream이라는 특징 때문에 장점은 중간 연산을 연결하여 연속해서 여러 번 수행할 수 있습니다.
최종 연산
소비는 Stream에 대한 최종 연산을 수행하는 것을 의미하며, 최종적인 목적물을 얻는 처리 과정을 의미합니다. 최종 연산을 수행하면 데이터 컬렉션(집합)이나 하나의 값(예, 합계)으로 결과값이 변환된 결과물을 얻을 수 있습니다.
최종 연산은 최종 결과물을 얻기 위한 목적으로 1번만 수행할 수 있습니다. 최종 연산이 수행되면, Stream은 닫혀서 더 이상 Stream API로 중간 연산이나 최종 연산을 다시 처리할 수 없습니다. 만일 데이터에 대한 추가적인 가공이 필요한 경우에는 새롭게 Stream을 생성해서 작업해야 합니다.
Stream의 데이터 구조가 생성, 가공, 소비의 형태로 처리가 되며, Stream의 데이터 연산 처리 시의 특징은 ‘지연평가(Lasy Evaluation)’이라는 특징이 있습니다.
- 지연평가(Lasy Evaluation)
중간 연산은 stream을 다른 stream으로 변환하거나 요소들을 변환하거나 필터링하는 작업을 수행합니다. 이러한 중간 연산들은 연산을 호출할 때 즉시 수행되지 않고, 최종 연산이 호출될 때까지 지연됩니다. 이를 ‘Lazy Evaluation(지연 평가)’이라고 하는데요.
데이터의 연속 흐름에 대해 중간 연산은 실행되고 있지 않다가 최종 연산을 만나게 되면, 그때 중간 연산이 실제로 실행됩니다. Stream의 데이터가 실제 처리되는 순서는 다음과 같은 특징이 있습니다.
- Stream의 데이터가 처리되는 순서
데이터 처리는 모든 데이터에 대해 하나의 함수가 끝나고(모두 처리되고 나서) 다른 함수가 수행되는 것이 아니라, 일련의 데이터가 나타난 흐름의 순서대로 처리됩니다. 앞선 데이터가 먼저 처리되고 뒤의 데이터가 나중에 처리되는 구조라고 이해할 수 있습니다.
마치 하수관에 오염물을 정화하는 과정에서 하수관에 1차 필터(침전), 2차 필터(정화), 최종 필터(소독)의 과정을 거친다고 할 때, 물이 흘러가는 순서대로 먼저 도달한 물이 각각 개별적으로 먼저 처리되고 나중에 도달하는 물은 나중에 처리되는 방식을 떠올리면 유사합니다.
Java Stream 사용법
그러면, 데이터 분석, 처리에 중요한 Java Stream의 내용을 본격적으로 알아보고, 직접 사용하는 방법을 알려드리겠습니다. Java Stream의 사용법은 Java Stream API의 생성, 중간 연산, 최종 연산 각각의 사용법을 구분해서 확인하면 이해가 더 명확하고, 향후 적용할 때 단계별로 적용이 가능합니다.
생성
Stream은 데이터의 집합인 컬렉션, 즉, 배열, ArrayList, Set, Map 등으로부터 생성할 수 있습니다. 컬렉션이 제공하는 stream() 메소드를 이용하면 쉽게 Stream을 만들어 낼 수 있습니다.
또한 배열도 Arrays 클래스 또는 Stream 클래스를 이용하면 Stream으로 쉽게 변환이 가능합니다.
또한, Stream에서 지원하는 generate() 메소드나 iterate() 메소드를 이용하여 다양한 형태의 데이터 Stream을 생성할 수 있습니다. generate()는 단순히 무한한 값을 생성하는 경우에 사용할 수 있고, iterate()는 다음 요소를 생성하기 위해서 이전 요소에 의존해서 만들어 낼 때 사용할 수 있습니다.
다음은 1부터 100까지 연속된 값의 Stream을 만드는 예시로 java.util.stream 패키지의 IntStream 클래스를 사용하는 예시와 Stream 클래스로 만드는 예시입니다.
1-100까지 중 10개의 난수를 만들어야 하는 경우, Random 클래스 또는 Stream 클래스로 만들어 낼 수 있습니다.
가공(중간 연산)
다음으로 가공(중간 연산)의 사용법입니다. 데이터에 대한 중간 연산으로 filter나 map 등을 통해 입맛대로 가공하는 역할을 합니다. 중간 연산의 종류로 filter, map, sorted, peek, distinct, limit 등이 있습니다.
filter 필터
map 변환
sorted 정렬
peak (중간 연산 중간에 처리 내용을 살펴보는 용도)
distinct 중복 제거
limit 개수 제한
이러한 중간 연산을 거치면 새로운 데이터의 stream이 만들어집니다.
소비(최종 연산)
마지막으로 최종 연산은 결과를 생성하거나 사이드이펙트를 만들기 위해서 사용됩니다. 데이터 처리를 하는 이유가 결국 최종 연산을 통해 원하는 데이터를 획득하는 데 있으니, 최종 연산으로 데이터 처리가 완결됩니다.
이러한 최종 데이터 처리에는 합계나 평균을 구하거나, 가공된 다른 데이터 컬렉션으로 변환하게 됩니다. 이러한 처리를 할 수 있는 대표적인 최종 연산의 종류로는 다음과 같은 것들이 있습니다.
1. 요소의 출력 :
forEach() – stream의 각 요소를 순회하면서 출력 등의 처리를 위해 사용.
2. 요소의 소모 :
reduce() – stream의 요소를 줄여나가면서 연산 수행. 처음 두 요소를 가지고 연산한 결과를 가지고 다음 요소와 연산해서 최종적인 값을 구하기 위해 사용.
3. 요소의 검색 :
findFirst(), findAny() – 특정 조건에 맞는 요소를 찾기 위해 사용. findFirst()는시퀀셜처리에 사용. findAny()는 병렬처리에 사용.
4. 요소의 검사 :
anyMatch(), allMatch(), noneMatch() – 조건에 맞는지 확인을 위해 사용.
5. 요소의 통계 :
count(), min(), max() – 요소의 개수, 최소값, 최대값을 구하기 위해 사용.
6. 요소의 연산 :
sum(), average() – 합계, 평균을 구하기 위해 사용.
7. 요소의 수집 :
collect() – stream의 요소를 수집하여 원하는 형태로 변환하기 위해서 사용. Java Collector 인터페이스를 매개변수로 호출하는데, Java에서 제공하는 Collectors 클래스에서 이미 만들어둔 method를 이용해서 요소를 변환해서 사용.
최종 연산에 사용되는 연산 중 forEach, reduce, collect, count, sum 등 몇 가지 사용법은 아래와 같습니다.
- forEach 각각의 요소에 특정 작업을 수행
- Count(개수), sum(합), min(최소값), max(최대값), average(평균)
- reduce stream의 각 요소를 결합하여 하나의 결괏값 생성
- collect stream을 컬렉션으로 변환
최종 연산에서 주의할 점은 최종 연산이 수행되고 나면, Stream이 소비가 완료되어 결과가 생성된 것이기 때문에 더 이상 Stream으로 처리할 수가 없다는 점입니다.
이것은 예를 들어 하수관을 통해 정화되어 가정집의 주전자에 들어가거나 사람이 음료로 마시고 나면, 더 이상 추가적인 하수처리를 할 수 없다는 것에 비유할 수 있을 것 같습니다.
다시 데이터를 가공 처리하려면 새롭게 Stream을 생성해야 다시 처리할 수 있습니다. 즉, 주전자의 물을 다시 하수로 내려보내야 재처리를 수행할 수 있는 것에 비유할 수 있습니다.
아래 예시를 보면 stream에 대해서 최종 연산인 forEach() 메소드가 실행이 되었으므로, 해당 Stream은 최종 연산을 수행하면 closed 상태가 됩니다.
따라서, 이후에 Stream에 대해서 중간 연산이나 최종 연산을 수행하게 되면 IllegalStateException 예외가 발생합니다. 이는 해당 Stream이 소비가 완료되어(닫혀서) 더 이상 처리할 수가 없는 상태이기 때문입니다.
데이터 생성, 가공, 소비의 각 단계에 따른 Java Stream의 사용법을 익혔다면, 이를 활용해서 대규모 데이터 처리 작업에 직접 도전해보길 추천드립니다. Stream을 활용하면 간결하고 효율적인 코드를 작성할 수 있어서 빅데이터 분석과 같은 작업이 더욱 쉬워집니다.
Stream을 다룰 줄 아는 Java 전문가를 채용하는 이유
요즘에는 다수의 로그 등에서 발생하는 데이터를 효과적으로 가공하여 대량의 데이터를 처리해야하는 경우가 많습니다. 그럴 때는 ‘Java Steam’을 활용한 병렬처리가 필수적입니다.
수많은 데이터를 빠르고 보기 편하게 작업하기 때문에, 데이터를 다뤄야하는 기업이 Java Stream을 사용한다면 데이터 처리 시 업무 효율성을 크게 높일 수 있습니다.
일반적인 웹서비스를 제공하는 모든 기업에서 백엔드 서버를 개발하는 개발자도 필수적으로 Java Stream API를 다룰 줄 알면 업무 효율성을 크게 높일 수 있습니다!
‘Java Stream API’를 사용한 Stream 연산은 간단하고 의미 있는 동작을 수행하므로 코드의 의도를 명확하게 전달하며, 가독성이 높은 코드를 통해 유지 보수 및 향후 서비스 변경이 필요할 경우 어려움 없이 코드를 변경할 수 있어 비용 및 자원을 아낄 수 있습니다.
그렇기 때문에 빅데이터 프로젝트 및 Spring Boot JPA 프로젝트와 같은 현대적인 개발 환경에서는 Stream을 적극적으로 활용하여 개발 및 업무 효율을 높이고 있는데요.
최신 개발 트렌드를 반영하는 동시에 빠르게 변화하는 시장 환경에서 데이터를 효율적으로 사용하여 우선순위를 가져올 ‘Java Stream 개발자’, 대한민국 No.1 인재 매칭 플랫폼 이랜서에서 매칭 받아보세요!
대한민국 No.1 IT 인재 매칭 플랫폼 이랜서
이랜서는 현장에 바로 투입될 수 있는 IT 전문가를 24년의 데이터로 검증해 매칭하는 대한민국 No.1 IT 인재 매칭 플랫폼입니다.
서버 구축 및 활용을 위한 자바, Node js, NestJS, TypeScript부터 프론트엔드 개발을 위한 React, Vue, Kotlin, 자바 스크립트와 .Net, Flutter, React Native 등의 크로스 플랫폼 전문가, 그리고 데이터 시스템 구축 및 수집, 분류, 분석을 도와줄 SQL(오라클, MySQL, MS SQL 등), DA, DBA, ETL등의 데이터 전문가까지 약 40만 명의 IT 전문가가 파트너십으로 등록되어 있습니다.
다른 채용 플랫폼에선 볼수없는 돋보적인 매칭 서비스!
24년의 데이터를 활용한 매칭 서비스로
기업들의 재의뢰율 98% 달성!
이랜서는 IT 전문가의 전문성부터 인성(협업 능력)까지 24년의 데이터로 검증해 프로젝트에 가장 적합한 IT 전문가를 매칭하는 IT 인재 매칭 플랫폼입니다.
24년의 데이터를 활용한 IT 인재 매칭 서비스
경력 기술서와 이력서만 보고 전문가를
매칭하는 채용 플랫폼과는 다른가요?
이랜서의 IT 인재 매칭 서비스는 경력 기술서와 이력서만 보고 전문가를 매칭하는 타 채용 플랫폼과는 다릅니다! 경력 기술서와 이력서만으로 검증이 어려운 인성(협업 능력)을 24년의 데이터를 활용하여 검증한 후 매칭하기 때문에 이랜서의 매칭 서비스를 사용하는 기업들은 IT 프로젝트 성향에 제일 적합한 IT 전문가를 매칭 받을 수 있습니다.
[약 1.5억 개의 사용자 데이터] /
[약 350만 개의 프리랜서 평가 데이터]
다른 곳에서는 확인할 수 없는 독보적인 데이터 수!
데이터로 검증된 IT 전문가를 매칭합니다!
기업들이 IT 전문가 채용 시 겪는 어려움이 바로 ‘인성 확인’입니다. 경력 기술서와 이력서만으로 전문성과 인성 모두 확인하기 어렵기 때문인데요.
이랜서는 24년의 ‘억 단위 데이터’를 활용해 IT 전문가의 전문성부터 인성까지 꼼꼼하게 확인/검증하여 IT 프로젝트에 가장 적합한 IT 전문가를 매칭합니다. 데이터를 통해 객관적이고 정확하게 검증하여 IT 전문가를 매칭하기 때문에, 이랜서를 사용하는 IT 기업들은 개발부터 유지보수, 서비스 개선 등 프로젝트의 성향 상관없이 최적합 IT 인재를 매칭 받을 수 있습니다.
개발부터 유지보수, 서비스 개선까지
IT 인재, 이랜서 하나로 해결됩니다!
이랜서는 기업에 가장 적합한 IT 전문가를 매칭하기 위해 프로젝트 등록 시 1:1 매니저를 매칭하여, 24시간 이내에 데이터로 검증된 IT 전문가를 매칭합니다. 요구사항이 있을 경우 주저하지 말고 매니저에게 모두 말해주세요!
서버 개발을 위한 Java 전문가부터 전사적 자원 관리 프로그램 도입을 위한 ERP, SAP, MES 전문가까지 기업에 필요한 IT 전문가를 데이터로 검증하여 매칭해 드립니다.
효율적인 데이터 처리와 활용을 위한
Java Stream 전문가를 찾으시나요?
대한민국 No.1 IT 인재 매칭 플랫폼 이랜서에
-> 회원 가입만 하세요.
-> 24시간 안에 전담 매니저가 연락을 드립니다.
-> 끝입니다. 이게 다냐구요? 네, 이게 다입니다.
-> 급하시다고요? 전화 주세요. 02-545-0042