• ABOUT
  • POSTS
  • GUESTBOOK

Β© 2025 BlueCool12 All rights reserved.

2025.08.12Java

πŸ”„ μžλ°” Stream API κ°€μ΄λ“œ - 생성, μ—°μ‚°, μž₯단점 정리

Stream APIλž€?
Java 8μ—μ„œ λ„μž…λœ Stream APIλŠ” 데이터 처리(필터링, λ³€ν™˜, 집계 λ“±)λ₯Ό ν•¨μˆ˜ν˜• μŠ€νƒ€μΌλ‘œ μž‘μ„±ν•  수 μžˆλ„λ‘ λ•λŠ” 도ꡬ이닀. 기쑴의 for 루프 기반 μ²˜λ¦¬λ³΄λ‹€ κ°„κ²°ν•˜κ³  가독성 높은 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 있게 도와쀀닀. 

 

*Stream λ™μž‘ 방식


Stream은 크게 쀑간 μ—°μ‚°κ³Ό μ΅œμ’… μ—°μ‚°μœΌλ‘œ λ‚˜λ‰œλ‹€. 
 

쀑간 μ—°μ‚° (Intermediate Operation)

데이터λ₯Ό λ³€ν™˜, 필터링, μ •λ ¬ν•˜λŠ” 과정을 λ‹΄λ‹Ήν•˜λ©° Stream νŒŒμ΄ν”„λΌμΈμ˜ 쀑간 λ‹¨κ³„μ—μ„œ μ‹€ν–‰λœλ‹€. 이 κ³Όμ •μ—μ„œ μ§€μ—° 연산이 μΌμ–΄λ‚œλ‹€. 
# μ§€μ—° μ—°μ‚° - μ΅œμ’… 연산이 호좜되기 μ „κΉŒμ§€ μ‹€μ œ μ²˜λ¦¬κ°€ 이루어지지 μ•Šκ³  μ΅œμ’… μ—°μ‚° μ‹œμ μ— ν•œ λ²ˆμ— μ‹€ν–‰λ˜λŠ” λ™μž‘ 방식

λŒ€ν‘œμ μΈ 쀑간 μ—°μ‚° λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€. 

java
filter(Predicate)             // 쑰건에 λ§žλŠ” μš”μ†Œλ§Œ ν•„ν„°λ§ν•œλ‹€. 
map(Function)                 // μš”μ†Œλ₯Ό λ‹€λ₯Έ ν˜•νƒœλ‘œ λ³€ν™˜ν•œλ‹€. 
flatMap(Function)             // μ€‘μ²©λœ ꡬ쑰λ₯Ό 평탄화 ν•œλ‹€. 
sorted() / sorted(Comparator) // μš”μ†Œλ₯Ό μ •λ ¬ν•œλ‹€. 
distinct()                    // 쀑볡을 μ œκ±°ν•œλ‹€. 
limit(long)                   // μ•žμ—μ„œλΆ€ν„° n개만 μ„ νƒν•œλ‹€. 
skip(long)                    // μ•žμ—μ„œλΆ€ν„° n개 κ±΄λ„ˆλ›΄λ‹€. 
peek(Consumer)                // μš”μ†Œλ₯Ό μ†ŒλΉ„ν•˜μ§€ μ•Šκ³  쀑간에 ν™•μΈν•œλ‹€. 

 


 

μ΅œμ’… μ—°μ‚° (Terminal Operation)

쀑간 μ—°μ‚°μ—μ„œ μ •μ˜ν•œ 처리 κ·œμΉ™μ„ μ‹€μ œλ‘œ μ‹€ν–‰ν•˜μ—¬ κ²°κ³Όλ₯Ό μƒμ„±ν•˜λŠ” λ‹¨κ³„λ‘œ μ΅œμ’… 연산이 ν˜ΈμΆœλ˜λŠ” μˆœκ°„ μ•žμ„œ νŒŒμ΄ν”„λΌμΈμ— μŒ“μ—¬ 있던 쀑간 연산듀이 ν•œ λ²ˆμ— μ‹€ν–‰λ˜κ³  슀트림이 λ‹«νžŒλ‹€. μ΅œμ’… 연산이 μˆ˜ν–‰λœ μ΄ν›„μ—λŠ” ν•΄λ‹Ή μŠ€νŠΈλ¦Όμ„ λ‹€μ‹œ μ‚¬μš©ν•  수 μ—†λ‹€. 

λŒ€ν‘œμ μΈ μ΅œμ’… μ—°μ‚° λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€. 

java
forEach(Consumer)                 // 각 μš”μ†Œμ— λŒ€ν•΄ μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€. 
collect(Collector)                // κ²°κ³Όλ₯Ό μ»¬λ ‰μ…˜μ΄λ‚˜ λ‹€λ₯Έ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•œλ‹€. 
reduce(BinaryOperator)            // μš”μ†Œλ₯Ό ν•˜λ‚˜μ˜ κ°’μœΌλ‘œ μ§‘κ³„ν•œλ‹€. 
count()                           // μš”μ†Œμ˜ 개수λ₯Ό λ°˜ν™˜ν•œλ‹€. 
anyMatch(Predicate)               // 쑰건을 λ§Œμ‘±ν•˜λŠ” μš”μ†Œκ°€ ν•˜λ‚˜λΌλ„ μžˆλŠ”μ§€ κ²€μ‚¬ν•œλ‹€. 
allMatch(Predicate)               // λͺ¨λ“  μš”μ†Œκ°€ 쑰건을 λ§Œμ‘±ν•˜λŠ”μ§€ κ²€μ‚¬ν•œλ‹€. 
noneMatch(Predicate)              // λͺ¨λ“  μš”μ†Œκ°€ 쑰건을 λ§Œμ‘±ν•˜μ§€ μ•ŠλŠ”μ§€ κ²€μ‚¬ν•œλ‹€. 
findFirst()                       // 첫 번째 μš”μ†Œλ₯Ό λ°˜ν™˜ν•œλ‹€. 
findAny()                         // μš”μ†Œ 쀑 ν•˜λ‚˜λ₯Ό λ°˜ν™˜ν•œλ‹€. (병렬 처리 μ‹œ 주둜 μ‚¬μš©)
min(Comparator) / max(Comparator) // μ΅œμ†Œκ°’ / μ΅œλŒ€κ°’μ„ λ°˜ν™˜ν•œλ‹€. 

 


 

*Stream 생성 방법


Javaμ—μ„œλŠ” λ‹€μ–‘ν•œ λ°©λ²•μœΌλ‘œ Stream을 생성할 수 μžˆλ‹€. 

java
// 1. μ»¬λ ‰μ…˜μ—μ„œ 생성
List<String> list = List.of("Blue", "Cool", "Good");
Stream<String> stream1 = list.stream();

// 2. λ°°μ—΄μ—μ„œ 생성
String[] arr = {"This", "is", "Array"};
Stream<String> stream2 = Arrays.stream(arr);

// 3. 숫자 λ²”μœ„μ—μ„œ 생성
IntStream intStream = IntStream.range(1, 5);
LongStream longStream = LongStream.rangeClosed(1, 5);

// 4. 직접 생성
Stream<Double> randoms = Stream.generate(Math::random).limit(5);

// 5. λΉŒλ” μ‚¬μš©
Stream<String> buildStream = Stream.<String>builder()
  .add("This")
  .add("is")
  .add("Builder")
  .build();


슀트림 생성뢀터 μ—°μ‚°κΉŒμ§€μ˜ 흐름은 λ‹€μŒκ³Ό κ°™λ‹€. 

java
List<String> names = List.of("BlueCool", "PYO", "MIN", "BlueMin");

// 길이가 4보닀 큰 μ΄λ¦„λ§Œ 필터링 -> λŒ€λ¬Έμžλ‘œ λ³€ν™˜ -> μ•ŒνŒŒλ²³μˆœ μ •λ ¬ -> 좜λ ₯
names.stream()
  .filter(name -> name.length() > 4) // 쀑간 μ—°μ‚°: 쑰건 필터링 (Predicate)
  .map(String::toUpperCase)          // 쀑간 μ—°μ‚°: λ¬Έμžμ—΄ λŒ€λ¬Έμž λ³€ν™˜ (Function)
  .sorted()                          // 쀑간 μ—°μ‚°: μ•ŒνŒŒλ²³μˆœ μ •λ ¬
  .forEach(System.out::println);     // μ΅œμ’… μ—°μ‚°: μš”μ†Œ 좜λ ₯ (Consumer)

 



Stream API의 κ°€μž₯ 큰 μž₯점은 κ°„κ²°ν•˜κ³  가독성 높은 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€λŠ” 점이닀. 기쑴의 반볡문 기반 μ½”λ“œμ— λΉ„ν•΄ 처리 과정을 μ§§κ³  λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ν•  수 있으며 filter(), map(), sorted()와 같은 연산을 μ²΄μ΄λ‹ν•˜μ—¬ β€œλ¬΄μ—‡μ„ 할지”에 μ§‘μ€‘ν•˜λŠ” μ„ μ–Έν˜• ν”„λ‘œκ·Έλž˜λ° μŠ€νƒ€μΌμ΄ κ°€λŠ₯ν•΄μ§„λ‹€. 

Stream은 μ•„μ£Ό νŽΈλ¦¬ν•˜μ§€λ§Œ λͺ¨λ“  μƒν™©μ—μ„œ 항상 μ΅œμ„ μ˜ 선택은 μ•„λ‹ˆλ‹€. μš°μ„  Stream은 1νšŒμ„±μ΄λ―€λ‘œ ν•œ 번 μ΅œμ’… 연산을 μˆ˜ν–‰ν•˜λ©΄ μž¬μ‚¬μš©μ΄ λΆˆκ°€ν•˜λ©° 데이터 크기가 μž‘κ±°λ‚˜ λ‹¨μˆœν•œ μ—°μ‚°μ—μ„œλŠ” 기쑴의 λ°˜λ³΅λ¬Έλ³΄λ‹€ 였히렀 μ„±λŠ₯이 λ–¨μ–΄μ§ˆ 수 μžˆλ‹€. 

특히 κΈ°λ³Έν˜•μ΄ μ•„λ‹Œ κ²½μš°μ—λŠ” λ°•μ‹±(Boxing)κ³Ό μ–Έλ°•μ‹±(Unboxing) κ³Όμ •μ—μ„œ λΆˆν•„μš”ν•œ μ˜€λ²„ν—€λ“œκ°€ λ°œμƒν•  수 있고 연산이 μ²΄μ΄λ‹λ˜λ©΄ 쀑간 κ³Όμ •μ˜ 디버깅이 μ–΄λ ΅κΈ° λ•Œλ¬Έμ— ν•„μš”ν•œ 경우 peek() 등을 ν™œμš©ν•˜μ—¬ 쀑간 값을 ν™•μΈν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€. 
 

이전 κΈ€
πŸ“‘ μžλ°” μžλ£Œν˜• μ™„μ „ 정리 [κΈ°λ³Έν˜•, μ°Έμ‘°ν˜•, Wrapper 클래슀]
λ‹€μŒ κΈ€
πŸ”£ λ©”νƒ€λ¬Έμž μ΄ν•΄λ‘œ μ‹œμž‘ν•˜λŠ” μ •κ·œν‘œν˜„μ‹
μž₯μ‹μš© 둜κ³