문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/92334
코딩테스트 연습 - 신고 결과 받기
문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다. 각 유저는 한 번에 한 명의
programmers.co.kr
문제 난이도 자체는 어렵지 않았으나, Map 을 사용하는 과정에서 Java 8 Stream 을 활용하기 전과 활용 후의 코드를 비교하고자 한다.
먼저, Java 8 Stream 을 활용하면 코드 가독성이 좋아지고, 코드량을 많이 줄일 수 있다는 장점이 있다.
아래는 문자열 리스트 중 특정 문자열로 시작하는 문자열 목록을 출력하는 예제 코드이다.
(Java 8 Stream X)
String[] id_list = {"muzi", "frodo", "apeach","neo"};
String[] report = {"muzi frodo", "apeach frodo", "frodo neo", "muzi neo", "apeach muzi"};
int k = 3;
List<String> listNotStream = new ArrayList<>();
for (String str : report) {
if (str.startsWith("muzi ")) {
listNotStream.add(str);
}
}
System.out.println(listNotStream);
(Java 8 Stream O)
- stream 을 사용한 후에는 map 혹은 filter 를 사용하면 for 선언문을 한것과 동일하다.
- map 함수 내에는 반복문 내에서 element 별로 특정 코드를 실행할 수 있다.
- filter 함수 내에는 반복문 내에서 if 문을 한개만 사용할 경우 유용하게 사용할 수 있다.
String[] id_list = {"muzi", "frodo", "apeach","neo"};
String[] report = {"muzi frodo", "apeach frodo", "frodo neo", "muzi neo", "apeach muzi"};
int k = 3;
List<String> listStream = Arrays.stream(report).filter(str -> str.startsWith("muzi ")).collect(Collectors.toList());
System.out.println(listStream);
자 이제 Java Stream 을 사용하기 전 후 코드를 비교해보자.
(문제에 대한 설명은 위 링크에서 확인하시면 됩니다)
Stream 활용 전
- id_list 에 있는 정보를 통해서, 인덱스 정보를 기억하기 위해서 map 을 사용하였으나 Stream 을 사용했다면 필요 없는 코드라고 생각된다.
- 그리고 중복을 제거하기 위해서 reportMap 이라는 2차원 배열을 사용하였는데, 메모리 공간을 많이 사용할 수도 있다.
public int[] solution(String[] id_list, String[] report, int k) {
// int[] answer = {};
int count = id_list.length;
int[][] reportMap = new int[count][count];
int[] reportCount = new int[count];
int[] answer = new int[count];
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < id_list.length; i++)
map.put(id_list[i],i);
for (int i = 0; i < report.length; i++) {
String[] rs = report[i].split(" ");
int fromIndex = map.get(rs[0]);
int toIndex = map.get(rs[1]);
if (reportMap[fromIndex][toIndex] == 0) {
reportMap[fromIndex][toIndex]+=1;
reportCount[toIndex]+=1;
}
}
for (int i = 0; i < reportCount.length; i++) {
if (reportCount[i] >= k) {
for (int j = 0; j < reportCount.length; j++) {
if (reportMap[j][i] > 0) {
answer[j]+=1;
}
}
}
}
return answer;
}
Stream 활용 후
- distinct 선언만으로도 for 선언문이 없어도 array 원소들의 중복을 제거한 리스트를 새로 만들 수 있다.
- 위 코드와 다르게 2차원 배열을 사용하지 않았고, 메모리도 절약할 수 있다.
public static int[] solution(String[] id_list, String[] report, int k) {
List<String> list = Arrays.stream(report).distinct().collect(Collectors.toList());
Map<String, Integer> count = new HashMap();
for (String item : list) {
String target = item.split(" ")[1];
count.put(target, count.getOrDefault(target, 0) + 1);
}
return Arrays.stream(id_list).map(_user -> {
String user = _user;
List<String> reportList = list.stream().filter(str -> str.startsWith(user + " ")).collect(Collectors.toList());
return reportList.stream().filter(s -> count.getOrDefault(s.split(" ")[1], 0) >= k).count();
}).mapToInt(Long::intValue).toArray();
}
그동안 Java 코딩을 할 때 Stream 을 잘 활용하지는 않았는데, 코드의 가독성도 좋고 효율적으로 코딩을 할 수 있어서 앞으로 많이 활용해야 겠다는 생각이 든다. 다음 문제부터는 Stream 을 최대한 활용해서 코드를 작성해 볼 예정입니다!
'코딩테스트' 카테고리의 다른 글
| [프로그래머스] H-index (0) | 2022.03.29 |
|---|---|
| [프로그래머스] 가장큰수 (0) | 2022.03.28 |
| [프로그래머스] 신규 아이디 추천 (0) | 2022.03.16 |
| [프로그래머스] 완주하지 못한 선수 (0) | 2021.08.30 |
| [프로그래머스] 기능개발 (0) | 2021.08.29 |