1️⃣ .map()
: 기존 스트림의 요소를 받아서, 어떤 함수로 바꿔서 새로운 스트림을 만듦(중간 연산) => 변환
ex :
List<String> names = List.of("Alice", "Bob", "Charlie");
// 각 이름을 대문자로 바꾸고 싶을 때
List<String> upperNames = names.stream()
.map(String::toUpperCase) // map이 각 요소를 변환
.toList();
System.out.println(upperNames); // [ALICE, BOB, CHARLIE]
2️⃣ .collect()
: 스트림의 최종 결과를 리스트, 세트, 맵 등 컬렉션으로 모을 때 사용 => 결과
ex :
List<String> names = List.of("Alice", "Bob", "Charlie");
List<String> upperNames = names.stream()
.map(String::toUpperCase) // 요소 변환
.collect(Collectors.toList()); // 리스트로 모으기
System.out.println(upperNames); // [ALICE, BOB, CHARLIE]
ex1:
List<String> names = List.of("Alice", "Bob", "Charlie");
List<String> result = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(result); // [ALICE, BOB, CHARLIE]
ex2:
record User(String name, int age) {}
List<User> users = List.of(
new User("Alice", 25),
new User("Bob", 30),
new User("Charlie", 20)
);
// User 객체 → 이름(String)만 추출
List<String> names = users.stream()
.map(User::name) // 중간 연산
.collect(Collectors.toList()); // 최종 연산
System.out.println(names); // [Alice, Bob, Charlie]
ex3:
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
// 제곱한 값을 리스트로
List<Integer> squared = numbers.stream()
.map(n -> n * n) // 변환
.collect(Collectors.toList());
System.out.println(squared); // [1, 4, 9, 16, 25]
ex4:
List<String> names = List.of("Alice", "Bob", "Charlie");
// 이름 → 길이(Map)
Map<String, Integer> nameLengthMap = names.stream()
.collect(Collectors.toMap(
name -> name, // key
name -> name.length() // value
));
System.out.println(nameLengthMap);
// {Alice=5, Bob=3, Charlie=7}
ex5:
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
// map으로 변환 후 합계
int sum = numbers.stream()
.mapToInt(n -> n * 2) // 중간 연산 (2배 변환)
.sum(); // 최종 연산 (합계)
System.out.println(sum); // 30
※ 여기서 4번 예시에는 처음 구현할 때, .map(name -> Map.entry(name, name.length()))과 같이 변환해서 써야하는거 아닌가? 싶어서 collect와 map의 차이에 혼동이 오기 시작했다.
=> 여기선 Collectors.toMap(k,v)가 각 요소를 받아 직접 만듦으로써, 변환과 수집(결과)를 동시에 내주어서 map을 쓰지 않고 간결하게 할 수 있음!