문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/134240
문자열의 수정이 빈번할거라 판단해서 StringBuilder를 사용했다. 문제의 로직에 대해 설명하기 보다는 StringBuilder를 사용하면서 껶었던 이슈들에 대해 정리해 보려고 한다.
자바 11부터 String 클래스에 추가된 메서드로 반복된 수만큼의 문자열을 삽입해주는 메서드이다.
매개변수 count에
String과 StringBuilder의 차이 중 하나는 immutable한 특징의 여부이다. immutable(불변의)한 String 클래스의 경우,
String str = "a";
str = "ab";
str 변수를 "a"에서 "ab"로 수정할 경우, str 변수가 참조하고 있던 주소에 "a" 값에서 "ab"값으로 바뀌는 것이 아니라, 새로운 주소에 "ab"가 생기고, str 변수가 그 새로운 주소를 참조하게 되고, "a" 인스턴스는 그대로 존재하고 나중에 garbage collector에 의해 처리된다.
반면, StringBuilder 클래스는 mutable하기 때문에 value값의 수정이 있더라도 새로운 인스턴스가 생성되는 것이 아닌 기존에 참조하던 주소의 값이 변경된다.
이러한 특징 때문에 String 클래스는 안정성 측면에서 더 좋고, 수정이 빈번한 경우에는 성능 상 StringBuilder 클래스가 더 좋다.
위의 특징들을 간과한 채로 reverse 메서드를 사용했다가 오답이 계속 발생했었다.
문제 내에서 문자열을 뒤집는 로직이 필요해서 StringBuider의 reverse 메서드를 사용했다.
public String solution(int[] food) {
StringBuilder first = new StringBuilder();
for (int i = 1; i < food.length; i++) {
first.append(String.valueOf(i).repeat(food[i] / 2));
}
return first + "0" + first.reverse();
}
위의 코드와 같이 StringBuilder 클래스의 first 변수를 reverse 메서드를 사용하니 return 값에 "0" 앞 부분까지 reverse 되는 현상이 발생했다.
이 이유가 2번 특징 때문인걸 꽤 나중에 알게 되었다. first 변수가 참조하는 값 자체가 reverse되었기 때문에 "0" 문자열 앞뒤로 모두 문자열이 뒤집혀서 반환되었다.
public String solution(int[] food) {
StringBuilder foods = new StringBuilder();
for (int i = 1; i < food.length; i++) {
foods.append(String.valueOf(i).repeat(food[i] / 2));
}
String player1 = foods.toString();
String player2 = foods.reverse().toString();
return player1 + "0" + player2;
}
이런 식으로 각각 String 클래스 변수에 문자열을 저장한 방식으로 해결하였다.