Lambda & Stream
Java λλ€ ννμκ³Ό Stream API
JAVA 8 μμ λλ€ ννμ(Lambda Expression) κ³Ό μ€νΈλ¦Ό API(Stream API) κ° λμ λλ©΄μ, μλ° μΈμ΄λ ν¨μν νλ‘κ·Έλλ° ν¨λ¬λ€μμ λΆλΆμ μΌλ‘ λ°μλ€μ΄κ³ λ³΄λ€ μ μΈμ μΈ μ½λ μμ±μ μ§μνκ² λμμ. μ΄λ‘μ¨ κ°λ°μλ λ°λ³΅λ¬Έμ΄λ μ΅λͺ ν΄λμ€μ μμ‘΄νλ λ°©μμ λ²μ΄λ, μ½λμ κ°κ²°μ± κ³Ό κ°λ μ± μ λμ΄κ³ λ©ν°μ½μ΄ νμ© λ±μ ν¨μ¨μ± λ κ°μ ν μ μκ² λμμ. μλμμλ λλ€ ννμκ³Ό μ€νΈλ¦Ό API μ κ°κ°μ κ°λ μ μ, λμ λ°°κ²½, λ¬Έλ², μ₯λ¨μ , νμ© μ¬λ‘λ₯Ό μ€λͺ ν κ±°μ.
Lambda Expression
μ μμ λμ
λ°°κ²½
λλ€ ννμ μ λ©μλ(ν¨μ)λ₯Ό νλμ μ(expression) μΌλ‘ νννλ λ¬Έλ²μΌλ‘, κ²°κ³Όμ μΌλ‘ λ¨μΌ λ©μλ μΈν°νμ΄μ€ (Functional Interface) μ μ΅λͺ
ꡬν체μ λλ±ν κΈ°λ₯μ μνν¨. λ€μ λ§ν΄, λλ€λ₯Ό μ¬μ©νλ©΄ μ½λλ₯Ό ν΅ν΄ λμ μ체λ₯Ό μΌκΈ κ°μ²΄ μ²λΌ λ€λ£° μ μμ΄μ, λ©μλμ μΈμλ‘ ν¨μν λμμ μ§μ μ λ¬νκ±°λ λ³μμ ν λΉνλ κ²μ΄ κ°λ₯ν΄μ§. Java 8 μ΄μ μλ μ΄λ¬ν λμ μ λ¬μ μν΄ μ΅λͺ
ν΄λμ€(μ΅λͺ
λ΄λΆ ν΄λμ€)λ₯Ό μ¬μ©νλλ°, μ½λκ° μ₯ν©ν΄μ§κ³ λΆνΈνλ€λ λ¬Έμ κ° μμμ. μλ₯Ό λ€μ΄ λ²νΌ ν΄λ¦ μ΄λ²€νΈ μ²λ¦¬λ 컬λ μ
μ λ ¬μ μν΄ κ°λ¨ν μμ
μ΄λΌλ ActionListener
λ Comparator
μΈν°νμ΄μ€λ₯Ό μ΅λͺ
ν΄λμ€ ννλ‘ κ΅¬νν΄μΌ νμ. λλ€ ννμμ μ΄λ¬ν λΆνΈν¨μ ν΄μνκΈ° μν΄ λ±μ₯νμΌλ©°, μλ°λ ν¨μν νλ‘κ·Έλλ°μ μ₯μ μ ν‘μνμ¬ λμ νλΌλ―Έν°ν(behavior parameterization) λ₯Ό κ°κ²°νκ² ννν μ μκ² λμμ. κ²°κ³Όμ μΌλ‘ λ³ννλ μꡬμ¬νμ μ μ°νκ² λμνκ³ , λΆνμν μ½λ μ€λ³΅κ³Ό 볡μ‘μ±μ μ€μ΄λ λ° ν¬κ² κΈ°μ¬νμμ.
λ¬Έλ²κ³Ό μ¬μ© λ°©λ²
Java μμ λλ€ ννμμ ν¨μν μΈν°νμ΄μ€ (μΆμ λ©μλκ° νλλ§ μ μΈλ μΈν°νμ΄μ€) μ ꡬνμ μ½κ² νννλ μμΌλ‘ μ¬μ©λ¨. κΈ°λ³Έ λ¬Έλ²μ λ€μκ³Ό κ°μ.
(λ§€κ°λ³μ λͺ©λ‘) -> { ν¨μ λ³Έλ¬Έ }
λ§€κ°λ³μ λͺ©λ‘ : ν¨μμ μ λ¬λ λ§€κ°λ³μλ₯Ό λμ΄ν¨. λ§€κ°λ³μκ° νλμ΄λ©΄ κ΄νΈ
()
λ₯Ό μλ΅ν μ μμ.->
: λλ€ νμ΄ν μ°μ°μλ‘ λ§€κ°λ³μμ ν¨μ λ³Έλ¬Έμ ꡬλΆν¨.ν¨μ λ³Έλ¬Έ : μ£Όμ΄μ§ λ§€κ°λ³μλ₯Ό μ΄μ©ν΄ μνν λ‘μ§μ μ μν¨. ν μ€λ‘ ννλλ κ²½μ° μ€κ΄νΈ
{}
λ₯Ό μλ΅ν μ μμΌλ©°, κ·Έ κ²°κ³Όκ°μ΄ λλ€μ λ°νκ°μ΄ λ¨. μ¬λ¬ μ€λ‘ μ΄λ£¨μ΄μ§ κ²½μ°{}
λΈλ‘ λ΄μ μμ±νκ³return
λ¬Έμ μ¬μ©ν¨.
λλ€ ννμμ νκ² νμ
λ¬Έλ§₯, μ¦ λ³μ μ μΈμ΄λ λ©μλ μΈμ λ±μ μμΉμμ ν΄λΉ λλ€μ νΈνλλ ν¨μν μΈν°νμ΄μ€μ νμ
μ ν΅ν΄ μ¬μ©λ¨. μλ₯Ό λ€μ΄ Runnable
μΈν°νμ΄μ€λ μΈμκ° μκ³ λ°νκ°μ΄ μλ run()
μΆμ λ©μλλ₯Ό κ°λλ°, μ΄λ₯Ό λλ€λ‘ νννλ©΄ () -> {...}
ννκ° λ¨. κ°λ¨ν μ¬μ© μλ₯Ό ν΅ν΄ λΉκ΅ν΄λ³΄λ©΄:
// Java 8 μ΄μ : μ΅λͺ
ν΄λμ€λ‘ μ°λ λ μ€ν
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello, World!");
}
});
th1.start();
// Java 8 μ΄ν : λλ€ ννμμΌλ‘ μ°λ λ μ€ν
Thread th2 = new Thread(() -> System.out.println("Hello, World!"));
th2.start();
μ μ½λμμ λ³Ό μ μλ―μ΄, λλ€λ₯Ό μ¬μ©νλ©΄ μ΅λͺ
ν΄λμ€ κ΅¬νμ λΉν΄ κ΅¬λ¬Έμ΄ ν¨μ¬ κ°κ²° ν΄μ§. μ΄ μΈμλ λλ€λ Comparator
μ κ°μ΄ νλμ λ©μλλ§ κ°μ§ μΈν°νμ΄μ€ ꡬνμ λ리 μ¬μ©λ¨. μλ₯Ό λ€μ΄ 리μ€νΈ μ λ ¬μ μν λΉκ΅μλ₯Ό λλ€λ‘ μ½κ² μ 곡ν μ μμ.
List<String> fruits = Arrays.asList("banana", "apple", "cherry");
// λλ€λ₯Ό μ¬μ©ν μ λ ¬: λ¬Έμμ΄ κΈΈμ΄λ₯Ό κΈ°μ€μΌλ‘ μ λ ¬
fruits.sort((a,b) -> a.length() - b.length());
System.out.println(fruits); // result : [apple, banana, cherry]
μμ sort
νΈμΆμμ λλ€ (a,b) -> a.length() - b.length()
λ Comparator<String>
μ compare(String o1, String o2)
λ©μλ ꡬνμ ννν κ²μ. μ΄μ²λΌ λλ€ λ¬Έλ²μ μ¬μ©νλ©΄, μΈν°νμ΄μ€λ₯Ό ꡬννλ μ΅λͺ
ν΄λμ€ μ μΈμ μ§μ νμ§ μκ³ λ νμν λμμ μ λ¬ν μ μμ. λν γΉλ§λ€ λ΄λΆμμλ μΈλΆ μ§μλ³μ λ₯Ό μ°Έμ‘°ν μ μλλ°, μ΄ κ²½μ° ν΄λΉ λ³μλ μλμΌλ‘ effectively final(μ¬μ€μ μμ) λ‘ μ·¨κΈλμ΄ λλ€μμ μμ νκ² νμ©λ¨.
μ₯μ
μ½λ κ°κ²°μ± ν₯μ : λλ€ ννμμ λμΌν κΈ°λ₯μ νλ μ½λλ₯Ό ν¨μ¬ μ§§κ³ λͺ ννκ² λ§λ€λ©°, 보μΌλ¬ νλ μ΄νΈ(boilerplate) μ½λλ₯Ό μ€μ¬μ€. μ΅λͺ ν΄λμ€ μ¬μ© λλΉ μμ±ν΄μΌ ν μ½λλμ΄ ν¬κ² κ°μνμ¬ κ°λ μ±μ΄ λμμ§.
ν¨μν νλ‘κ·Έλλ° μ§μ : ν¨μ μ체λ₯Ό κ°μΌλ‘ μ λ¬ν μ μμΌλ―λ‘, λ©μλμ μΈμλ‘ λμμ λκΈ°κ±°λ 컬λ μ μ μ²λ¦¬νλ λ‘μ§μ μ λ΅μ²λΌ λ°κΏ λΌμ°λ λ± λμ νλΌλ―Έν°ν κ° μ¬μμ§.
ννλ ₯ μ¦κ° : λλ€μ ν¨κ» λμ λ μ€νΈλ¦Ό API μ κ²°ν©νμ¬, 볡μ‘ν μ°μ°μ μ μΈμ μ΄κ³ μ§κ΄μ μΈ λ°©μ μΌλ‘ ννν μ μμ. 무μμ ν μ§μ μ§μ€ν μ½λ μμ±μ΄ κ°λ₯ν΄μ§κ³ , loop λ 쑰건문 λ±μ ꡬν μΈλΆμ¬νμ μ¨κ²¨μ§.
λ©±λ±μ± λ° λ©ν°μ€λ λ νμ© : λλ€λ‘ μ λ¬λλ ν¨μλ λΆμμ©μ΄ μλλ‘ μμ±λλ κ²μ΄ κΆμ₯λλλ°, μ΄λ° νΉμ± λλΆμ μ€νΈλ¦Όμμ λ³λ ¬ μ²λ¦¬ λ₯Ό ν λλ μμ νκ² μ μ©ν μ μμ. λν λ³λ ¬ μ€νΈλ¦Ό λ±μ μ¬μ©ν λ λ³λμ μ€λ λ κ΄λ¦¬ μ½λ μμ΄λ λ©ν°μ½μ΄ νμ©μ΄ κ°λ₯ν΄μ§.
νμ€ ν¨μν μΈν°νμ΄μ€ νμ© : μλ° 8 μμλ
java.util.function
ν¨ν€μ§μ λ€μν μ©λμ ν¨μν μΈν°νμ΄μ€(Consumer, Function, Predicate λ±) κ° μ 곡λμ΄ μμ΄, λλ€λ₯Ό μ¬μ©ν νμ€νλ νλ‘κ·Έλλ° μ€νμΌμ νμ©ν μ μμ. μ΄λ API μ€κΌ λ° μ¬μ© μΈ‘λ©΄μμ μΌκ΄μ±μ λΆμ¬ν¨.
λ¨μ
μ΄κΈ° κ°λ μ± μ ν : λλ€ λ¬Έλ²μ΄ μ΅μνμ§ μμ κ°λ°μμκ²λ μ€νλ € μ½λμ μλ―Έλ₯Ό νμ νκΈ° μ΄λ €μΈ μ μμ. μ΅λͺ ν΄λμ€μ λΉν΄ μ½λμ λͺ μμ±μ΄ λ¨μ΄μ§ μ μλ€ λ μ§μ λ μμΌλ©°, μ΄λ μΈν°νμ΄μ€μ μ΄λ€ λ©μλλ₯Ό ꡬνν κ²μΈμ§ λ°λ‘ μκΈ° μ΄λ €μ μ²μμ νΌλμ μ€ μ μμ.
λλ²κΉ μ΄λ €μ : λλ€ ννμ μ체μλ μ΄λ¦μ΄ μκ³ μ΅λͺ ν¨μ ννλ‘ μ€νλκΈ° λλ¬Έμ, λλ²κ±°λ‘ μΆμ ν λ μ€ν νΈλ μ΄μ€κ° μ§κ΄μ μ΄μ§ μμ μ μκ³ , λλ€ λ΄λΆμμ μμΈ λ°μ μ μ΄λ μ§μ μΈμ§ νμ μ΄ λ€μ κΉλ€λ‘μΈ μ μμ. λν λλ€ λ΄ μ½λλ νλμ ν΄λ‘μ (Closure) λ‘ μ·¨κΈλλ―λ‘, μ€κ°μ λ³μ κ°μ μ°μ΄λ³΄κ±°λ νκΈ°κ° μ ν΅μ μΈ λ£¨νμ λΉν΄ λ²κ±°λ‘μ.
μ ν μ¬ν : λλ€λ μ€μ§ νλμ μΆμ λ©μλλ§μ κ°μ§ μΈν°νμ΄μ€ μ λν΄μλ§ μ¬μ©ν μ μμΌλ―λ‘ (
@FunctionalInterface
), κΈ°μ‘΄μ μ¬λ¬ λ©μλλ₯Ό κ°μ§ νμ μ λλ€λ‘ μ§μ ꡬνν μλ μμ. λν λλ€ λ³Έλ¬Έμμ checked μμΈ λ₯Ό λμ§λ €λ©΄ ν΄λΉ μΈν°νμ΄μ€μ κ·Έ μμΈκ° μ μΈλμ΄ μμ΄μΌ νλ λ±μ μμΈ μ²λ¦¬ μ νμ΄ μμ.μΈλΆ μν λ³κ²½μ μ ν : λλ€ λ΄λΆμμλ μΈλΆ μ§μ λ³μλ₯Ό λ³κ²½ν μ μμ. (ν΄λΉ λ³μλ effectively final μ΄μ΄μΌ ν¨.) λ°λΌμ λλ€μ λ΄λΆμμ μΈλΆ μνλ₯Ό λ³κ²½νλ λ‘μ§μ μ»΄νμΌ νμμ μ νλλ©°, μ΄λ¬ν μ€κ³λ λΆμμ©μ λ°©μ§νμ§λ§ λλ‘λ λΆνΈν¨μΌλ‘ λκ»΄μ§ μ μμ.(
AtomicInteger
λ λ°°μ΄ λ±μΌλ‘ μ°ν κ°λ₯νμ§λ§ κΆμ₯λμ§λ μμ.)μ±λ₯ λ° μ»΄νμΌ μ€λ²ν€λ : λλ€ μ체λ μλ° μ»΄νμΌλ¬κ° λ΄λΆμ μΌλ‘ invokedynamic κΈ°λ°μΌλ‘ ꡬννκ±°λ μ¨κ²¨μ§ ν΄λμ€ νμΌμ μμ±νμ¬ μ²λ¦¬ν¨. μΌλ°μ μΌλ‘ μ΄λ‘ μΈν μ€ν μ±λ₯ λΆνκ° ν¬μ§ μμ§λ§, μλ° 8 μ΄κΈ°μλ λλ€ μ¬μ© μ 첫 νΈμΆμ μ½κ°μ μ§μ°μ΄ μλ€λ λ³΄κ³ λ μμμ. νμ§λ§ JIT μ΅μ νλ‘ λλΆλΆ μμλλ©°, λλ€ ννμ κ·Έ μμ²΄λ‘ ν° μ±λ₯μμ λ¨μ μ μμ ( μ£Όλ‘ μ€νΈλ¦Ό μ¬μ© μμ μ€λ²ν€λκ° μ΄μ)
Stream API
Stream μ μλ° 8 μμ 컬λ μ λ±μ λ°μ΄ν°λ₯Ό μ²λ¦¬νκΈ° μν΄ λμ λ ν¨μν API μ. μ€νΈλ¦Όμ μ¬μ©νλ©΄ μ μΈν(declarative) λ°©μμΌλ‘ 컬λ μ μ μμλ€μ λ€λ£° μ μμΌλ©°, 볡μ‘ν λ°μ΄ν° μ²λ¦¬λ λ©μλ 체μ΄λμ ν΅ν΄ νμ΄νλΌμΈ ννλ‘ κ΅¬νν μ μμ. μ€νΈλ¦Όμ νλ§λλ‘ λ°μ΄ν° μμλ€μ μ°μμ μΈ νλ¦ μΌλ‘μ, μ΄μ λν΄ μΌλ ¨μ μ€κ° μ°μ°κ³Ό μ΅μ’ μ°μ°μ μ μ©νμ¬ μνλ κ²°κ³Όλ₯Ό μ»λ κ²μ κ°λ₯μΌ ν¨. μ΄λ¬ν μ κ·Ό λ°©μμ μ ν΅μ μΈ λ°λ³΅λ¬Έμ λΉν΄ κ°κ²°νκ³ μλμ μ§μ€λ μ½λ λ₯Ό μμ±ν μ μκ² ν΄μ£Όλ©°, λ΄λΆ λ°λ³΅μ ν΅ν΄ μ΅μ ν μ¬μ§λ₯Ό λ¨κ²¨λκ±°λ μμ½κ² λ³λ ¬ μ²λ¦¬λ‘ μ νν μ μλ€λ μ₯μ μ΄ μμ.
μ€νΈλ¦Ό API μ λμ λ°°κ²½μλ μ¬λ¬ κ°μ§ μ΄μ κ° μμ.
첫째, λλ λ°μ΄ν° μ²λ¦¬μ νμμ± μ. λ©ν°μ½μ΄ μλμ ν¨κ³Όμ μΌλ‘ 컬λ μ
μ μ²λ¦¬νλ €λ©΄, κ°λ°μκ° μΌμΌμ΄ μ°λ λλ₯Ό κ΄λ¦¬νμ§ μκ³ λ λ°μ΄ν° μ²λ¦¬λ₯Ό λ³λ ¬νν μ μλ κ³ μμ€μ μΆμνκ° μꡬλμμ. μ€νΈλ¦Όμ parallelStream()
λ©μλλ₯Ό ν΅ν΄ κ°λ¨ν λ°μ΄ν° λ³λ ¬ μ²λ¦¬λ₯Ό ꡬνν μ μκ² ν΄μ€.
λμ§Έ, κ°λ μ±κ³Ό μ μ§λ³΄μμ± κ°μ μ. μ€νΈλ¦Όμ μ¬μ©νλ©΄ 루νμ μ‘°κ±΄λ¬Έμ΄ λ€μμΈ μ½λλ³΄λ€ μλκ° λͺ νν νμ΄νλΌμΈμ ꡬμ±ν μ μκ³ , μ΄λ₯Ό ν΅ν΄ λΉμ¦λμ€ λ‘μ§μ μΌκ΄λ ννλ‘ νν ν μ μμ.
λ§μ§λ§μΌλ‘, ν¨μν νλ‘κ·Έλλ°μ κ°λ
μ λμ
ν¨μΌλ‘μ¨ λΆμμ© μλ μ²λ¦¬ λ₯Ό μ§ν₯νκ³ , νν°λ§, λ§€ν, μ λ ¬, κ·Έλ£Ήν λ± κ³΅ν΅ μ°μ°μ μ¬μ¬μ© κ°λ₯νκ² νμ€ν νκ³ μ ν μλκ° μμ. μλ₯Ό λ€μ΄ κ³Όκ±°μλ λ°λ³΅λ¬Έκ³Ό 쑰건κ²μ¬λ₯Ό ν΅ν΄ μ§μ ꡬνν΄μΌ νλ λ‘μ§λ€μ μ΄μ λ filter
, map
, collect
λ±μ μ¬μ¬μ© κ°λ₯ν μ°μ°μΌλ‘ νμ€μ© ννν μ μμ.
μ€νΈλ¦Ό ꡬ쑰μ μ£Όμ μ°μ°
μ€νΈλ¦Ό API μ μ¬μ© λ°©λ²μ λ°μ΄ν° μμ€ λ‘λΆν° μ€νΈλ¦Ό κ°μ²΄λ₯Ό μμ±νκ³ , μ¬λ¬ μ€κ° μ°μ° (Intermediate Operation) μ μ°μμΌλ‘ μ μ©ν λ€, μ΅μ’ μ°μ° (Terminal Operation) μΌλ‘ κ²°κ³Όλ₯Ό μ»λ ν¨ν΄μΌλ‘ μμ½λ¨. μ΄λ μ€κ° μ°μ°λ€μ μ€νΈλ¦Όμ 리ν΄νμ¬ λ€μ μ°μ°κ³Ό 체μ΄λλλ©°, μ€μ μ²λ¦¬(load) λ μ΅μ’ μ°μ°μ΄ νΈμΆλ λ λΉλ‘μ μΌμ΄λλ μ§μ° νκ°(lazy evaluation) νΉμ±μ κ°μ§. μ€νΈλ¦Όμ μ 체μ μΈ κ΅¬μ±μμλ λ€μκ³Ό κ°μ.
λ°μ΄ν° μμ€(Data Source) : μ€νΈλ¦Όμ μΆλ°μ μ΄ λλ μμλ€μ λͺ¨μμ. μλ₯Ό λ€μ΄ 컬λ μ μ
stream()
λ©μλλ₯Ό νΈμΆνκ±°λ, λ°°μ΄μArrays.stream(array)
λ₯Ό μ¬μ©νκ±°λ, νμΌ I/O μμFiles.lines(path)
λ‘ μ€νΈλ¦Όμ μμ±ν μ μμ.μ€κ° μ°μ°(Intermediate Operation) : μ€νΈλ¦Όμ λ°μ΄ν°λ₯Ό νν°λ§νκ±°λ λ³ννλ μ°μ°λ€μ. λνμ μΌλ‘
filter(Predicate)
,map(Function)
,sorted()
,distinct()
,limit()
λ±μ΄ μμΌλ©°, μ¬λ¬ μ€κ° μ°μ°μ νμ΄νλΌμΈ νν λ‘ μ°κ²°ν μ μμ. μ€κ° μ°γ λμ lazy νκ² λμνμ¬, λ¨λ μΌλ‘λ μ€νλμ§ μκ³ κ²°κ³Όλ λ°λ‘ μ»μ μ μμ. μ€κ° μ°μ°μ κ²°κ³Όλ μ¬μ ν μ€νΈλ¦Όμ΄λ―λ‘, μ΄μ΄μ λ€μ μ°μ°μ μ μ©ν μ μμ.μ΅μ’ μ°μ°(Terminal Operation) : μ€νΈλ¦Ό νμ΄νλΌμΈμ λμ λ§Ίλ μ°μ°μΌλ‘, μ΅μ’ μ°μ°μ΄ νΈμΆλ λ κ·Έμ μμΌ μ΄μ κΉμ§μ λͺ¨λ μ€κ° μ°μ°μ΄ μ μ©λλ©΄μ μ€μ μ²λ¦¬ κ° μνλκ³ κ²°κ³Όκ° μμ±λ¨. μ΅μ’ μ°μ°μλ μ€νΈλ¦Ό μμλ₯Ό μλͺ¨νμ¬ κ²°κ³Όλ₯Ό μ»λ
collect()
,count()
,reduce()
λ, λΆμμ©μ λ°μμν€λforEach()
λ±μ΄ μμ. μ΅μ’ μ°μ°μ νΈμΆνλ©΄ ν΄λΉ μ€νΈλ¦Όμ μ¬μ¬μ©ν μ μκ²(μλͺ¨λ μνλ‘) λ¨.
μμ
λ¬Έμμ΄ λ¦¬μ€νΈ μμ νΉμ 쑰건μ λ§λ λ¬Έμμ΄λ§ νν°λ§νμ¬ λλ¬Έμλ‘ λ³νν λ€ μ λ ¬νμ¬ κ²°κ³Ό 리μ€νΈλ₯Ό μ»λ μμ μ, κΈ°μ‘΄ λ°©μκ³Ό μ€νΈλ¦Όμ νμ©ν λ°©μμΌλ‘ λΉκ΅νλ μμ μ.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Anna", "Alex");
List<String> resultList = new ArrayList<>();
// κΈ°μ‘΄ λ°©μ: λ°λ³΅λ¬Έ μ¬μ©
for(String name : names) {
if(name.startWith("A")) {
resultList.add(name,toUpperCase());
}
}
Collections.sort(resultList); // μ λ ¬
System.out.println(resultList); // result : [ALEX, ALICE, ANNA]
//μ€νΈλ¦Ό μ¬μ© : νμ΄νλΌμΈ ꡬμ±
List<String> resultList2 = names.stream()
.filter(n -> n.startWith("A"))
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println(resultList2);
μ μμ μμ μ μ μλ―μ΄, μ€νΈλ¦Όμ μ¬μ©νλ©΄ λ°μ΄ν° μ²λ¦¬ κ³Όμ μ λ§μΉ SQLμ μ§μλ¬Έ μ²λΌ μ μΈμ μΌλ‘ μμ±ν μ μμ. names.stream()
μΌλ‘ 리μ€νΈμ λν μ€νΈλ¦Όμ μ»μ λ€, filter
λ‘ "A" λ‘ μμνλ μ΄λ¦λ§ κ±Έλ¬λ΄κ³ , map
μΌλ‘ λλ¬Έμ λ³ν, sorted
λ‘ μ λ ¬, λ§μ§λ§μ collect
λ‘ λ¦¬μ€νΈλ‘ λͺ¨μΌλ μΌλ ¨μ κ³Όμ μ λ©μλ 체μ΄λ μΌλ‘ νννμ. κΈ°μ‘΄ λ°©μκ³Ό λΉκ΅νλ©΄ μ½λμ ν μκ° μ€μ΄λ€κ³ , κ° λ¨κ³μ μλκ° μ½λμ λͺ
νν λλ¬λλ κ²μ λ³Ό μ μμ.
λν μ€νΈλ¦Όμ μ§μ° μ€ν λλΆμ, λ§μ½ μ νμ΄νλΌμΈμμ filter
ν λ°λ‘ 첫 λ²μ§Έ λ§€μΉ μμλ§ μ°Ύλ μ°μ°(μ: findFirst()
) μ μ΅μ’
μ°μ°μΌλ‘ μ¬μ©νλ€λ©΄ 쑰건μ λ§λ λλ¨Έμ§ μμλ€μ κ΅³μ΄ λλ¬Έμ λ³νμ΄λ μ λ ¬μ μννμ§ μκ³ λ μ²λ¦¬λ₯Ό λ§μΉ μ μμ. μ΄λ¬ν lazy νΉμ± μ λΆνμν μ°μ°μ μ€μ¬ μ±λ₯μ λμΌ μ μλ μμμ.
λ§μ§λ§μΌλ‘ μ€νΈλ¦Όμλ κΈ°λ³Έν νΉν μ€νΈλ¦Ό (IntStream
, LongStream
, DoubleStream
) λ μ 곡λ¨. μ΄λ₯Ό νμ©νλ©΄ λ°μ±(boxing)/μΈλ°μ± μμ΄ κΈ°λ³Έ νμ
μ λλ λ°μ΄ν°λ ν¨μ¨μ μΌλ‘ μ²λ¦¬ν μ μμ. μλ₯Ό λ€μ΄, IntStream.range(1,100)
μ 1 λΆν° 99κΉμ§μ μ μ μ€νΈλ¦Όμ μμ±νλ©°, mapToObj
λ mapToInt
λ±μ λ©μλλ₯Ό ν΅ν΄ κ°μ²΄ μ€νΈλ¦Όκ³Ό κΈ°λ³Έν μ€νΈλ¦Ό κ° μ νλ κ°λ₯ν¨.
μ€νΈλ¦Όμ μ₯μ
μ½λ μ μΈμ± & κ°κ²°ν¨ : μ€νΈλ¦Όμ μ¬μ©νλ©΄ μλ£ μ²λ¦¬μ λν μλλ₯Ό μ½λμ νννκΈ° μ¬μ. 무μμ νκ³ μ νλμ§λ₯Ό λ©μλ νΈμΆ 체μΈμΌλ‘ 보μ¬μ£Όλ―λ‘, for-loop λ±μ λΉν΄ μ½λκ° κ°κ²°νκ³ λ Όλ¦¬μ νλ¦μ΄ λΆλͺ ν¨ . νΉν λ€λ¨κ³ μ²λ¦¬ (νν°λ§ -> λ§€ν -> μ λ ¬ -> μ§κ³ λ±) λ₯Ό μ€μ²© 루ν μμ΄ νμ΄νλΌμΈμΌλ‘ ννν μ μμ΄, 볡μ‘ν μ²λ¦¬λ λΉκ΅μ μ½κΈ° μ½κ² μμ±ν μ μμ.
μ¬μ¬μ© κ°λ₯ν μ°μ° :
filter
,map
,reduce
,collect
λ± μ€νΈλ¦Όμ΄ μ 곡νλ λ§μ μ°μ°μ μ΄λ―Έ μ΅μ νλμ΄ μκ³ λ²μ©μ μΌλ‘ μΈ μ μλ κ³ μμ€ ν¨μλ€μ. μ΄λ₯Ό νμ©νλ©΄ κ°λ°μκ° μ μμ€μμ μΌμΌμ΄ μμ±ν΄μΌ νλ λ‘μ§μ μ€μ΄κ³ μμ°μ± μ λμΌ μ μμ.λΆλ³μ±κ³Ό λΆμμ© μ΅μν : μ€νΈλ¦Ό μ°μ°μ μλ³Έ λ°μ΄ν°λ₯Ό λ³κ²½νμ§ μκ³ μλ‘μ΄ κ²°κ³Όλ₯Ό μμ±ν¨. λν μ€κ° μ°μ°λ€μ μμ ν¨μνμΌλ‘ λμνλλ‘ κΆμ₯λλ―λ‘(μΈλΆ μνλ₯Ό λ³κ²½νμ§ μλ λλ€), νλ‘κ·Έλ¨μ λΆμμ©(side effect) μ μ€μ΄κ³ λ²κ·Έλ₯Ό μλ°©νλ λ° λμμ΄ λ¨. μ΄λ° νΉμ±μ μ½λμ ν μ€νΈ μ©μ΄μ±κ³Ό μμΈ‘ κ°λ₯μ±λ ν₯μμν΄.
Lazy μ°μ°μΌλ‘ μΈν μ΅μ ν : μμ μ€λͺ ν λλ‘, μ€νΈλ¦Όμ μ§μ° νκ°λ₯Ό ν΅ν΄ νμν λλ§ μ°μ°μ μ€ννλ―λ‘ μ±λ₯ μ΅μ ν μ λμμ΄ λ¨. μλ₯Ό λ€μ΄ μ¬λ¬ λ¨κ³μ μ€κ° μ°μ°μ΄ μλλΌλ, μ΅μ’ μ°γ λμ΄
findFirst
λanyMatch
μ²λΌ μΌλΆλ§ νμλ‘ νλ μμ μ΄λ©΄ μ 체 μμλ₯Ό λκΉμ§ μ²λ¦¬νμ§ μμ. λν νμ΄νλΌμΈ λ΄λΆμμ μ°μ°λ€μ΄ 루ν ν¨μ (loop fusion) λμ΄ ν λ²μ μνλ‘ μ²λ¦¬λ μλ μμ.λ³λ ¬ μ²λ¦¬ μ©μ΄ : μ€νΈλ¦Όμ κ°μ₯ ν° νΉμ§ μ€ νλλ μμ¬μ΄ λ³λ ¬νμ.
stream()
λμparallelStream()
μ νΈμΆνλ©΄ λ΄λΆμ μΌλ‘ Fork/Join νλ μμν¬λ₯Ό νμ©νμ¬ μ¬λ¬ μ½μ΄μ μμ μ λΆλ°°ν¨. ν° μ»¬λ μ μ λν΄ CPU μ½μ΄λ₯Ό λͺ¨λ νμ©ν¨μΌλ‘μ¨ μ±λ₯ ν₯μμ κΈ°λν μ μμΌλ©°, μ΄λ₯Ό ꡬννκΈ° μν 볡μ‘ν λ©ν°μ€λ λ μ½λλ₯Ό μ§μ μμ±ν νμκ° μμ.λ€μν λ°μ΄ν° μμ€ μ²λ¦¬ : 컬λ μ λΏλ§ μλλΌ λ°°μ΄, νμΌ , I/O μ±λ λ± λ€μν μμ€λ‘λΆν° μ€νΈλ¦Όμ μμ±νμ¬ κ³΅ν΅λ λ°©μμΌλ‘ μ²λ¦¬ν μ μμ. μλ₯Ό λ€μ΄
Files.lines()
λ‘ νμΌμ κ° μ€μ μ€νΈλ¦ΌμΌλ‘ μ»μ΄ μ²λ¦¬νκ±°λ,Pattern.compile(...).splitAsStream()
μΌλ‘ λ¬Έμμ΄μ μ€νΈλ¦ΌμΌλ‘ λ€λ£¨λ λ± μμ© λ²μκ° λμ.
μ€νΈλ¦Όμ λ¨μ
μλ λ°μ΄ν°μ λν μ€λ²ν€λ : μ€νΈλ¦Όμ μμ±νκ³ λλ€λ₯Ό νΈμΆνλ©° μ¬λ¬ κ°μ²΄λ₯Ό μμ±νλ λΉμ© λλ¬Έμ, μμ£Ό λ¨μν λ°λ³΅μ΄λ μλμ λ°μν° μ²λ¦¬μλ μ€νλ € μ ν΅μ μΈ λ£¨νλ³΄λ€ λ릴 μ μμ . μμ»¨λ° λ¨μν 리μ€νΈμ λ΄μ©μ μΆλ ₯νλ κ²½μ°μλ
names.stream().forEach(...)
보λ€λ κ°νλ forλ¬Έ(for(String name : names)
) μ΄ μ±λ₯μ μ 리ν μ μμ. μμ μμ μ μΌκ΄μ μΌλ‘ μ€νΈλ¦Όμ μ μ©νλ κ²μ νΌνλ κ²μ΄ μ’μ.λλ²κΉ λ° μΆμ μ΄λ €μ : λλ€μ λ§μ°¬κ°μ§λ‘ μ€νΈλ¦Ό νμ΄νλΌμΈμ μ½λμ νλ¦μ΄ μ°μμ μΌλ‘ μ΄μ΄μ§λ―λ‘, μ€κ° λ¨κ³μμ κ°μ λμΌλ‘ νμΈνκ±°λ λλ²κΉ νλ κ²μ΄ μ΄λ €μ. λλ²κ±°λ‘λ λλ€ λ΄λΆλ₯Ό μΌμΌμ΄ λ€μ¬λ€ λ΄μΌ νκ³ , μ½λμμΌλ‘λ
peek()
κ°μ λλ²κΉ μ© μ°μ°μ μΆκ°ν΄μΌ μ€κ°κ°μ λ³Ό μ μμ. 볡μ‘ν μ€νΈλ¦Ό νμ΄νλΌμΈμ μ μ§λ³΄μ μμ μ΄ν΄νλ λ° μκ°μ΄ 걸릴 μ μμ.μ¬μ¬μ© λΆκ° λ° νκ³ : μΌλ¨ μ΅μ’ μ°μ°μ ν΅ν΄ ν λ² μλΉλ μ€νΈλ¦Όμ λ€μ μ¬μ©ν μ μμ. νμν κ²½μ° μλ‘μ΄ μ€νΈλ¦Όμ λ§λ€μ΄μΌ νλ―λ‘, λμΌν λ°μ΄ν°λ₯Ό λ λ² μνν΄μΌ νλ€λ©΄ μ°¨λΌλ¦¬ μ²μλΆν° κ·Έ μ²λ¦¬λ₯Ό ν΅ν©νκ±°λ κ²°κ³Όλ₯Ό 컬λ μ μ λͺ¨μ ν μ¬μ¬μ©νλ λ°©λ²μ κ³ λ €ν΄μΌ ν¨. λν μ€νΈλ¦Όμ λ³Έμ§μ μΌλ‘ μμ°¨μ μΈ μ²λ¦¬ μΆμν μ κ°κΉκΈ° λλ¬Έμ, νΉμ μΌμ΄μ€ (μ : μμλ₯Ό νλ μ²λ¦¬νλ€κ° μΈλΆ μ 건μ λ°λΌ 루νλ₯Ό μ 체λ₯Ό μ€λ¨ν΄μΌ νλ κ²½μ° λ±) μμλ μ€νΈλ¦Όλ§μΌλ‘ ꡬνμ΄ κΉλ€λ‘κ±°λ λΆμ ν© ν μ μμ.
λ³λ ¬ μ€νΈλ¦Ό μ£Όμμ¬ν : λ³λ ¬ μ€νΈλ¦Όμ μ¬μ©ν λλ 곡μ μν λ³κ²½μ΄λ μ€λ λ μμ μ± μ μ μν΄μΌν¨. μλͺ»νλ©΄ κ²½μ 쑰건 (race condition) μ΄ λ°μνκ±°λ, κΈ°λνμ§ μμ κ²°κ³Όκ° λμ¬ μ μμ. λν λ³λ ¬ μ²λ¦¬ μ체μ μ€λ²ν€λ λλ¬Έμ, λ°μ΄ν°λμ΄ μΆ©λΆν ν¬μ§ μμΌλ©΄ λ³λ ¬νκ° μνλ₯Ό λΌ μ μμ.
λ©λͺ¨λ¦¬ μλΉ : μ€νΈλ¦Όμ μλ³Έ λ°μ΄ν°λ₯Ό λ³κ²½νμ§ μκ³ μλ‘ μ²λ¦¬ κ²°κ³Όλ₯Ό λ§λ€μ΄λ΄λ ν¨ν΄μ΄λ―λ‘, νν°λ§μ΄λ λ§€ν κ²°κ³Όλ₯Ό μλ‘μ΄ μ»¬λ μ μΌλ‘ μμ§νλ©΄ κ·Έλ§νΌ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©ν¨. μΌλ°μ μΈ λ£¨νμμ μ μ리μμ μμ (in-place) νλ κ²κ³Ό λ¬λ¦¬, νμμ λ°λΌ μΆκ° λ©λͺ¨λ¦¬ ν λΉμ΄ μΌμ΄λ μ μμ. νΉν 무ν μ€νΈλ¦Ό λλ λ§€μ° ν° μ€νΈλ¦Όμ μλͺ» μ¬μ©ν κ²½μ° λ©λͺ¨λ¦¬ λΆμ‘±μ μ£Όμν΄μΌν¨.
Last updated
Was this helpful?