μ•„μ΄ν…œ 46: μŠ€νŠΈλ¦Όμ—μ„œλŠ” λΆ€μž‘μš© μ—†λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λΌ

πŸ’‘
슀트림 νŒŒμ΄ν”„λΌμΈ ν”„λ‘œκ·Έλž˜λ°μ˜ 핡심은 λΆ€μž‘μš© μ—†λŠ” ν•¨μˆ˜ 객체에 μžˆλ‹€. 슀트림 뿐 μ•„λ‹ˆλΌ 슀트림 κ΄€λ ¨ 객체에 κ±΄λ„€μ§€λŠ” λͺ¨λ“  ν•¨μˆ˜ 객체가 λΆ€μž‘μš©μ΄ μ—†μ–΄μ•Ό ν•œλ‹€. μŠ€νŠΈλ¦Όμ„ μ˜¬λ°”λ‘œ μ‚¬μš©ν•˜λ €λ©΄ μˆ˜μ§‘κΈ°λ₯Ό 잘 μ•Œμ•„λ‘¬μ•Ό ν•œλ‹€. κ°€μž₯ μ€‘μš”ν•œ μˆ˜μ§‘κΈ° νŒ©ν„°λ¦¬λŠ” toList, toSet, toMap, groupingBy, joining 이닀.

슀트림 νŒ¨λŸ¬λ‹€μž„

  • μŠ€νŠΈλ¦Όμ€ κ·Έμ € 또 ν•˜λ‚˜μ˜ APIκ°€ μ•„λ‹Œ, ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— κΈ°μ΄ˆν•œ νŒ¨λŸ¬λ‹€μž„
  • 슀트림이 μ œκ³΅ν•˜λŠ” ν‘œν˜„λ ₯, 속도, (상황에 λ”°λΌμ„œλŠ”) 병렬성을 μ–»μœΌλ €λ©΄ APIλŠ” 말할 것도 μ—†κ³  이 νŒ¨λŸ¬λ‹€μž„κΉŒμ§€ ν•¨κ»˜ λ°›μ•„λ“€μ—¬μ•Ό ν•œλ‹€.
  • 슀트림 νŒ¨λŸ¬λ‹€μž„μ˜ 핡심은 계산을 일련의 λ³€ν™˜μœΌλ‘œ μž¬κ΅¬μ„±ν•˜λŠ” λΆ€λΆ„
    • μ΄λ•Œ 각 λ³€ν™˜ λ‹¨κ³„λŠ” κ°€λŠ₯ν•œ ν•œ 이전 λ‹¨κ³„μ˜ κ²°κ³Όλ₯Ό λ°›μ•„ μ²˜λ¦¬ν•˜λŠ” 순수 ν•¨μˆ˜μ—¬μ•Ό 함. (순수 ν•¨μˆ˜λž€ 였직 μž…λ ₯만이 결과에 영ν–₯을 μ£ΌλŠ” ν•¨μˆ˜. λ‹€λ₯Έ κ°€λ³€ μƒνƒœλ₯Ό μ°Έμ‘°ν•˜μ§€ μ•Šκ³  ν•¨μˆ˜ μŠ€μŠ€λ‘œλ„ λ‹€λ₯Έ μƒνƒœλ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠλŠ”λ‹€.)
    • μ΄λ ‡κ²Œ ν•˜λ €λ©΄ 슀트림 연산에 κ±΄λ„€λŠ” ν•¨μˆ˜ κ°μ²΄λŠ” λͺ¨λ‘ λΆ€μž‘μš©μ΄ μ—†μ–΄μ•Ό 함
// Uses the streams API but not the paradigm--Don't do this! Map<String, Long> freq = new HashMap<>(); try (Stream<String> words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); }); } // Proper use of streams to initialize a frequency table ( Map<String, Long> freq; try (Stream<String> words = new Scanner(file).tokens()) { freq = words .collect(groupingBy(String::toLowerCase, counting())); } System.out.println(freq);
  • μœ„μ˜ μ½”λ“œ μ˜ˆμ‹œλŠ” 슀트림 μ½”λ“œλ₯Ό κ°€μž₯ν•œ 반볡적 μ½”λ“œμž„. μ½”λ“œμ˜ λͺ¨λ“  μž‘μ—…μ΄ 쒅단 연산인 forEach μ—μ„œ μΌμ–΄λ‚˜κ²Œ 되고 μ΄λ•Œ μ™ΈλΆ€ μƒνƒœλ₯Ό μˆ˜μ •ν•˜λŠ” λžŒλ‹€λ₯Ό μ‹€ν–‰ν•˜λ©΄μ„œ λ¬Έμ œκ°€ 생김
  • forEach 연산은 쒅단 μ—°μ‚° 쀑 κΈ°λŠ₯이 κ°€μž₯ 적고 κ°€μž₯ β€˜λœβ€™ μŠ€νŠΈλ¦Όλ‹€μ›€. λŒ€λ†“κ³  반볡적이라 병렬화 ν•  μˆ˜λ„ μ—†μŒ. forEach 연산은 슀트림 계산 κ²°κ³Όλ₯Ό 보고할 λ•Œλ§Œ μ‚¬μš©ν•˜κ³ , κ³„μ‚°ν•˜λŠ” λ°λŠ” μ“°μ§€ 말자.

Collectors(java.util.stream.Collectors)

  • μŠ€νŠΈλ¦Όμ„ μ‚¬μš©ν•˜λ €λ©΄ κΌ­ λ°°μ›Œμ•Ό ν•˜λŠ” μƒˆλ‘œμš΄ κ°œλ…
  • μΆ•μ†Œ(reduction; 슀트림의 μ›μ†Œλ“€μ„ 객체 ν•˜λ‚˜μ— μ·¨ν•©ν•œλ‹€λŠ” 의미) μ „λž΅μ„ μΊ‘μŠν™”ν•œ λΈ”λž™λ°•μŠ€ 객체라고 μƒκ°ν•˜λ©΄ 됨

μˆ˜μ§‘κΈ° λ©”μ„œλ“œλ“€

toList(), toSet(), toCollection(collectionFactory)
// Pipeline to get a top-ten list of words from a frequency table List<String> topTen = freq.keySet().stream() .sorted(comparing(freq::get).reversed()) .limit(10) .collect(toList()); System.out.println(topTen);
  • toMap() β€” λ§΅ μˆ˜μ§‘κΈ°
  • groupingBy β€” μž…λ ₯으둜 λΆ„λ₯˜ ν•¨μˆ˜λ₯Ό λ°›κ³  좜λ ₯μœΌλ‘œλŠ” μ›μ†Œλ“€μ„ μΉ΄ν…Œκ³ λ¦¬λ³„λ‘œ λͺ¨μ•„ 놓은 맡을 담은 μˆ˜μ§‘κΈ°λ₯Ό λ°˜ν™˜
  • partitioningBy
  • minBy
  • maxBy
  • joining