얄코의 제대로 파는 자바/섹션9 함수형 프로그래밍
스트림 문제 풀이
백엔드 개발자
2024. 8. 17. 19:49
아래와 같은 User.csv가 있다고 할 때, 아래의 CSV 데이터를 조회하여 아래와 같은 결과를 출력한다고 하자.
// User.csv
이름, 취미, 소개
김프로, 축구:농구:야구, 구기종목 좋아요
정프로, 개발:당구:축구, 개발하는데 뛰긴 싫어
앙몬드, 피아노, 죠르디가 좋아요 좋아좋아너무좋아
죠르디, 스포츠댄스:개발, 개발하는 죠르디 좋아
박프로, 골프:야구, 운동이 좋아요
정프로, 개발:축구:농구, 개발도 좋고 운동도 좋아
문제 1.1
위와 같은 데이터를 조회하여 각 취미를 선호하는 인원이 몇 명인지 계산하여라.
출처: https://mangkyu.tistory.com/116 [MangKyu's Diary:티스토리]
//1. 데이터를 어떻게 저장하나>
// 클래스로 만들어서 클래스 배열로?
TestUser [] testUsers = {
new TestUser("김프로", "축구:농구:야구", " 구기종목 좋아요")
,new TestUser("정프로", "개발:당구:축구", "개발하는데 뛰긴 싫어")
,new TestUser("앙몬드", "피아노", " 죠르디가 좋아요 좋아좋아너무좋아")
,new TestUser("죠르디", " 스포츠댄스:개발", " 개발하는 죠르디 좋아")
,new TestUser("박프로", " 골프:야구", "운동이 좋아요")
,new TestUser("정프로", " 개발:축구:농구", " 개발도 좋고 운동도 좋아")
};
//2. 각 취미를 선호하는 인원이 몇명인지 계산하기
//일단 :를 기준으로 나누는게 필요할듯
//취미만 따로 어떻게 빼서 분류하지?
/*
1. :으로 데이터 분리한다.
2. 각 데이터 별로 Map에 이름, 인원으로 넣고, key가 같은게 있으면 value +1
같은게 없으면 신규로 넣도록 하고, 마지막에 entryset으로 출력한다면?
*/
String [] hobbyData = Arrays.stream(testUsers).
map(testUser -> testUser.getHobby().trim()+":").
reduce(String::concat).orElse("").split(":");
System.out.println(hobbyData[0]);
Set<Map.Entry<String, Integer>> entries = Arrays.stream(hobbyData).
collect(
Collectors.toMap(
i -> i,
i -> 1,
Integer::sum// 병합함수 : 동일한 키가 존재하면 값을 더한다.
)
).entrySet();
System.out.println(entries);
GPT 답변
// 취미별 빈도 계산
Map<String, Long> hobbyCount = Arrays.stream(testUsers)
.map(testUser -> testUser.getHobby().trim()) // 취미 문자열 추출
.flatMap(hobbies -> Arrays.stream(hobbies.split(":"))) // 취미 분리
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); // 취미별 빈도 계산
// 결과 출력
hobbyCount.forEach((hobby, count) -> System.out.println(hobby + ": " + count));
코드 설명
스트림 생성 및 취미 추출:
Arrays.stream(testUsers)로 TestUser 배열에서 스트림을 생성합니다.
map(testUser -> testUser.getHobby().trim())로 각 TestUser 객체에서 취미 문자열을 추출하고, trim()을 사용하여 문자열의 앞뒤 공백을 제거합니다.
취미 문자열 분리:
flatMap(hobbies -> Arrays.stream(hobbies.split(":")))로 각 취미 문자열을 ":" 구분자로 나누어 스트림으로 변환합니다. flatMap을 사용하여 취미를 하나의 스트림으로 평탄화합니다.
취미별 빈도 계산:
collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))를 사용하여 각 취미별로 빈도를 계산하고, Map<String, Long>으로 수집합니다. 여기서 Function.identity()는 취미를 키로 사용하고, Collectors.counting()은 각 취미의 발생 횟수를 셉니다.
결과 출력:
hobbyCount.forEach((hobby, count) -> System.out.println(hobby + ": " + count))를 사용하여 각 취미와 그 빈도를 출력합니다.