문자열 s에 나타나는 문자를 큰 것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수를 구현한다.
대문자는 소문자보다 작은 것으로 간주한다.
import java.util.Collections;
import java.util.Arrays;
class Solution {
public String solution(String s) {
String answer = "";
Character[] charArr = new Character[s.length()];
for (int i = 0; i < s.length(); i++) {
charArr[i] = s.charAt(i);
}
Arrays.sort(charArr, Collections.reverseOrder());
for (char chr : charArr) {
answer += String.valueOf(chr);
}
return answer;
}
}
Collections.reverseOrder()는 왜 char[]에 못 쓸까?처음엔 char[]에 바로 Collections.reverseOrder()를 쓰려고 했음.
근데 Collections.reverseOrder()는 Comparator를 반환하는데,
Comparator는 객체 타입에만 적용 가능함.
char는 primitive 타입 → Comparator 적용 불가
→ Character[] (래퍼 클래스 배열) 로 바꿔야 함
그리고 배열 정렬에는 Collections.sort()가 아니라 Arrays.sort() 를 써야 함.
Collections.sort()는 List만 받음.
// char[]에는 Comparator 적용 불가
// Arrays.sort(charArr, Collections.reverseOrder()); ← 오류
// Character[]로 바꿔야 가능
Character[] charArr = new Character[s.length()];
Arrays.sort(charArr, Collections.reverseOrder()); // OK
String += 반복의 문제점answer += String.valueOf(chr); // 매번 새 String 객체 생성
String은 불변 객체라서 += 할 때마다 새 객체가 만들어짐.
반복문 안에서 쓰면 불필요한 객체가 계속 생성됨.
→ StringBuilder 로 교체
StringBuilder sb = new StringBuilder();
for (char chr : charArr) {
sb.append(chr);
}
return sb.toString();
import java.util.Collections;
import java.util.Arrays;
class Solution {
public String solution(String s) {
Character[] charArr = new Character[s.length()];
for (int i = 0; i < s.length(); i++) {
charArr[i] = s.charAt(i);
}
Arrays.sort(charArr, Collections.reverseOrder());
StringBuilder sb = new StringBuilder();
for (char chr : charArr) {
sb.append(chr);
}
return sb.toString();
}
}
import java.util.Collections;
import java.util.stream.Collectors;
class Solution {
public String solution(String s) {
return s.chars()
.mapToObj(n -> String.valueOf((char) n))
.sorted(Collections.reverseOrder())
.collect(Collectors.joining());
}
}
| 단계 | 설명 |
|---|---|
s.chars() | IntStream 반환 (UTF-16 코드값) |
.mapToObj(n -> String.valueOf((char) n)) | int → char 캐스팅 후 String으로 변환 |
.sorted(Collections.reverseOrder()) | 역순 정렬 |
.collect(Collectors.joining()) | 구분자 없이 하나의 String으로 합치기 |
왜 (char) n을 String으로 변환해야 하나?
Collectors.joining()은 Stream<CharSequence>를 기대함.
Character는 CharSequence를 구현하지 않아서 바로 못 씀.
→ String.valueOf((char) n)으로 String으로 변환해야 함
왜 chars()는 IntStream을 반환하나?
chars()는 CharSequence 인터페이스의 메서드.
Java에 CharStream이 없어서 IntStream으로 대신 반환함.
char[]를 Arrays.stream()으로 변환하는 것도 지원 안 됨 (int[], long[], double[]만 지원).
| for문 + StringBuilder | Stream | |
|---|---|---|
| 가독성 | 더 직관적 | 체인이 길어지면 복잡 |
| 성능 | StringBuilder 재사용 | 중간 객체 생성 있음 |
| 적합한 상황 | 이 문제처럼 단순 정렬 | 필터링·변환이 복잡할 때 |
Stream이 항상 더 좋은 게 아님. 이 문제에서는 for문 버전이 더 읽기 쉬움.
Collections.reverseOrder()는 객체 타입에만 적용 가능 → primitive는 래퍼 클래스로Arrays.sort(), List 정렬은 Collections.sort()String += → StringBuilder로char[]은 Arrays.stream() 지원 안 됨 → Stream 쓰려면 String.chars() 활용Character는 CharSequence 구현 안 함 → Collectors.joining() 쓰려면 String으로 변환 필요