Open dpwns523 opened 1 year ago
Collectors.toMap()
/*
* 아래의 코드에서 keyMapper, valueMapper( 키와 값을 생산하는 두 함수 인자 )를 통해
* Key-Value 형태로 매핑해줘야함
*/
Map<keyType, valueType> map = strings.stream()
.collect(Collectors.toMap(keyMapper, valueMapper));
/*
* 예제1) List -> 요소의 길이를 key값으로 매핑한 Map 자료형으로 변환
* keyMapper : 각 요소.length()의 결과를 key값으로 사용
* valueMapper : Function.identity() 메서드는 값이 실제 요소인 경우 사용
* 결과 : {4=pear, 5=apple, 6=banana}
*/
List<String> strings = Arrays.asList("apple", "banana", "pear");
Map<Integer, String> map = strings.stream()
.collect(Collectors.toMap(String::length, Function.identity()));
System.out.println(map);
/*
* 예제2) key값이 중복되는 경우 Collectors.toMap()
* 결과 : java.lang.IllegalStateException: Duplicate key
*/
List<String> strings = Arrays.asList("apple", "banana", "grape");
Map<Integer, String> map = strings.stream()
.collect(Collectors.toMap(String::length, Function.identity()));
System.out.println(map);
/*
* 예제3) Key의 중복 해결 : mergeFunction
* 3rd 인자로 mergeFunction을 넣어서 충돌발생시 이를 해결하기 위한 방안 미리 제공
* (oldVal, newVal) -> oldVal : 새로운값과 기존값 충돌시, 기존값을 유지
* 결과 : {5=apple, 6=banana}
*/
List<String> strings = Arrays.asList("apple", "banana", "grape");
Map<Integer, String> map = strings.stream()
.collect(Collectors.toMap(
String::length,
Function.identity(),
(oldVal, newVal) -> oldVal
));
System.out.println(map);
/*
* 예제4-1) LinkedHashMap 형태의 결과 반환 Supplier<M> mapFactory
* 4st 인자로 Map 객체를 제공( 새롭게 생성한 emptyMap 제공 )
* 결과 : {5=apple, 6=banana, 4=pear}
*/
List<String> strings = Arrays.asList("apple", "banana", "pear", "grape");
Map<Integer, String> map = strings.stream()
.collect(Collectors.toMap(
String::length,
Function.identity(),
(oldVal, newVal) -> oldVal,
LinkedHashMap:: new
));
System.out.println(map);
/*
* 예제4-2) LinkedHashMap 형태의 결과 반환 Supplier<M> mapFactory
* 4st 인자로 Map 객체를 제공( 이전에 생성한 notEmptyMap 제공 )
* 결과 : {1004=서울 17반 북스터디, 5=apple, 6=banana, 4=pear}
*/
List<String> strings = Arrays.asList("apple", "banana", "pear", "grape");
LinkedHashMap<Integer, String> notEmptyMap = new LinkedHashMap<>();
notEmptyMap.put(1004, "서울 17반 북스터디");
Map<Integer, String> map = strings.stream()
.collect(Collectors.toMap(
String::length,
Function.identity(),
(oldVal, newVal) -> oldVal,
() -> notEmptyMap
));
System.out.println(map);
Stream 요소를 그룹화하여 수집하기
groupingBy() vs toMap() : 특정 기준값을 key로 둘 다 key-value값을 가지는데 무슨 차이가 있을까?
/*
* 1. valueMapper 인자에 리스트를 반환하는 메서드를 넣어라
* 2. mergeFunction 인자에 중복키값 발생시, 대체가 아니라 누적하는 메서드를 넣어라
* 결과 : {4=[pear], 5=[apple, grape], 6=[banana]}
*/
public class Temp {
public static void main(String[] args) {
List<String> strings = Arrays.asList("apple", "banana", "grape", "pear");
Map<Integer, List<String>> map = strings.stream()
.collect(Collectors.toMap(
String::length,
Temp::stringToList,
Temp::merge
));
System.out.println(map);
}
/* 새로운 key값을 가진 value인 경우, 리스트를 생성하고 담아서 반환 */
static List<String> stringToList(String str) {
List<String> strs = new ArrayList<>();
strs.add(str);
return strs;
}
/* 중복되는 key값을 가진 value인 경우, 기존의 리스트에 병합하여 반환 */
static List<String> merge(List<String> oldVal, List<String> newVal) {
oldVal.addAll(newVal);
return oldVal;
}
}
문제
컬렉터의 toMap 메서드에 대해 알아보기
contents - 세부 내용
그룹화 메서드로 Collectors.toMap을 이용하는 방법도 있는데 책에서는 소개되지 않아서 알아보는게 좋을 것 같습니다
참고
6.3 ~ 6.5절