Java Stream API - map() & flatMap()
Java 8μμ λμ λ Stream APIλ 컬λ μ μ μ²λ¦¬νλ ν¨κ³Όμ μΈ λ°©λ²μ μ 곡νλ€. κ·Έ μ€μμλ map()κ³Ό flatMap() λ©μλλ λ°μ΄ν° λ³νκ³Ό μ²λ¦¬μ μμ΄ ν΅μ¬μ μΈ μν μ νλ€.
1. map()
<R> Stream<R> map(
Function<? super T, // T : μ
λ ₯ νμ
(μλ³Έ μ€νΈλ¦Όμ μμ νμ
)
? extends R> mapper // R : μΆλ ₯ νμ
(μλ‘μ΄ μ€νΈλ¦Όμ μμ νμ
)
)
map() λ©μλλ μ€νΈλ¦Όμ κ° μμλ₯Ό λ€λ₯Έ μμλ‘ λ³ννλ 1:1 λ§€νμ μννλ€. μ λ ₯ μμ νλλΉ μ νν νλμ μΆλ ₯ μμκ° μμ±λλ€.
μ£Όμ νΉμ§
- κ° μμλ₯Ό λ 립μ μΌλ‘ λ³ν
- μ€νΈλ¦Όμ μμ κ°μ μ μ§ (one-to-one)
- μλ³Έ λ°μ΄ν° ꡬ쑰 보쑴
- λ°ν νμ : Stream<R> (Rμ λ³νλ νμ )
μμ μ½λ
// λ¬Έμμ΄ κΈΈμ΄ λ³ν
List<String> words = Arrays.asList("Java", "Stream", "API");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
// κ²°κ³Ό: [4, 6, 3]
// κ°μ²΄ λ³ν
List<User> users = getUserList();
List<String> userNames = users.stream()
.map(User::getName)
.collect(Collectors.toList());
2. flatMap()
<R> Stream<R> flatMap(
Function<? super T, // T : μ
λ ₯ νμ
(μλ³Έ μ€νΈλ¦Όμ μμ νμ
)
? extends Stream<? extends R>> mapper // R : μΆλ ₯ νμ
(μλ‘μ΄ μ€νΈλ¦Όμ μμ νμ
)
)
flatMap()μ μ€μ²©λ μ€νΈλ¦Ό ꡬ쑰λ₯Ό λ¨μΌ λ λ²¨λ‘ νλ©΄ννλ©΄μ λ³ννλ μμ μ μννλ€. κ° μμλ₯Ό μ€νΈλ¦ΌμΌλ‘ λ³νν ν, νλμ μ€νΈλ¦ΌμΌλ‘ λ³ν©νλ€.
μ£Όμ νΉμ§
- μ€μ²© ꡬ쑰λ₯Ό λ¨μΌ λ λ²¨λ‘ νλ©΄ν
- μμλ₯Ό 0κ° μ΄μμ μμλ‘ λ³ν κ°λ₯ (one-to-many)
- 컬λ μ μ κ³μΈ΅ ꡬ쑰 μ κ±°
- λ°ν νμ : Stream<R> (μ€μ²©λ μ€νΈλ¦Όμ λ¨μΌ μ€νΈλ¦ΌμΌλ‘ λ³ν)
- κ° μμ± λ°©λ²
- 0κ° κ° λ°ν: Stream.empty()
- μ¬λ¬ κ° λ°ν: Stream.of(a, b, c)
Stream<List<Integer>> νμ μ numbers.stream()μ flatMapμ μ¬μ©ν΄ Stream<Integer>λ‘ λ³ν ν 리μ€νΈλ‘ λ°ν.
flatMapμ κ° μ λ ₯κ°μ λ°λΌ λ€λ₯Έ κ°μλ₯Ό λ°ννλ μ μ°ν μ²λ¦¬λ κ°λ₯νλ€.
class User {
private String name;
private List<String> emails;
// getters, setters...
}
List<String> allEmails = users.stream()
.flatMap(user -> user.getEmails().stream())
.collect(Collectors.toList());
μ μ½λμμλ λͺ¨λ email μΆλ ₯μ μν΄ κ° Userλ³ emailμ΄ κ°μμ 리μ€νΈλ‘ ꡬλ³λμ΄ emailμ΄ μΆλ ₯λμ§ μκ³ λͺ¨λ emailμ νλμ 리μ€νΈλ‘ μ²λ¦¬νκΈ° μν΄ flatMapμ μ¬μ©νμλ€.
3. μ€μ νμ© μ¬λ‘
class Order {
private List<Product> products;
// getters, setters...
}
class Product {
private String name;
private double price;
// getters, setters...
}
// λͺ¨λ μ£Όλ¬Έμ μ΄ κΈμ‘ κ³μ°
double totalValue = orders.stream()
.flatMap(order -> order.getProducts().stream())
.mapToDouble(Product::getPrice)
.sum();
// λͺ¨λ μ ν μ΄λ¦ μΆμΆ
List<String> productNames = orders.stream()
.flatMap(order -> order.getProducts().stream())
.map(Product::getName)
.distinct()
.collect(Collectors.toList());
μ΄λ κ² κ° μ£Όλ¬Έμ΄λ μ ν λ³μ΄ μλ μ 체μ μΈ ν΅κ³λ νλͺ©μ μΆμΆνκ³ μΆμ κ²½μ° flatMapμ΄ κ°λ ₯ν λκ΅¬κ° λλ€.