문제
내가 작성한 정답
for , String
: String은 불변객체이기 때문에, 문자열을 수정할 때마다 새로운 String 객체가 생성된다. 이 과정은 메모리 할당과 복사가 필요하므로 반복문 내에서 문자열을 계속 추가하면, 매번 새로운 String 객체가 생성되어 성능이 저하된다

class Solution {
public String solution(int[] numLog) {
String answer = "";
for(int i =0; i<numLog.length-1; i++){
int d = numLog[i+1]-numLog[i];
if(d == 1) answer += "w";
else if(d == -1) answer += "s";
else if(d == 10) answer += "d";
else if(d == -10) answer += "a";
}
return answer;
}
}
for , StringBuilder
:StringBuilder는 가변객체로, 내부적으로 버퍼를 사용하여 문자열을 효율적으로 수정할 수 있다. → 문자열을 추가할 때마다 새로운 객체를 생성할 필요가 없으므로 성능이 더 좋다.

class Solution {
public String solution(int[] numLog) {
StringBuilder sb = new StringBuilder();
for(int i =0; i<numLog.length-1; i++){
int d = numLog[i+1]-numLog[i];
if(d == 1) sb.append("w");
else if(d == -1) sb.append("s");
else if(d == 10) sb.append("d");
else if(d == -10) sb.append("a");
}
return sb.toString();
switch, StringBuilder
class Solution {
public String solution(int[] numLog) {
StringBuilder sb = new StringBuilder();
for(int i =0; i<numLog.length-1; i++){
switch (numLog[i+1]-numLog[i]){
case 1 : sb.append("w"); break;
case -1 : sb.append("s"); break;
case 10 : sb.append("d"); break;
case -10 : sb.append("a"); break;
}
}
return sb.toString();
}
}
StreamAPI
import java.util.stream.*;
class Solution {
public String solution(int[] numLog) {
return IntStream.range(0,numLog.length-1)
.mapToObj(i->
switch (numLog[i+1]-numLog[i]){
case 1 -> "w";
case -1 ->"s";
case 10 -> "d";
case -10 ->"a";
default -> "";
})
.collect(Collectors.joining());
// String::concat을 사용하면 각 결합마다 새로운 문자열 객체가 생성되어 성능이 저하된다.
.reduce("", String::concat);
}
}
yield
주로 switch 표현식에서 사용된다. yield는 특정 블록에서 값을 반환할 때 사용되며 기존의 switch 문에서 break를 사용하는 것과는 다르게 yield를 사용하면 switch 표현식의 각 경우에서 값을 반환할 수 있다.
int result = switch (value) {
case 1 -> "one";
case 2 -> "two";
default -> "unknown";
};
int result = switch (value) {
case 1 : yield "one";
case 2 : yield "two";
default : yield "";
};
다른 사람들의 정답
import java.util.*;
class Solution {
// 문자열과 정수를 매핑하는 HashMap을 선언
public Map<String, Integer> hm;
public String solution(int[] numLog) {
String answer = "";
hm = new HashMap<>(); // HashMap을 초기화
// 방향과 그에 해당하는 이동 값을 HashMap에 저장합니다.
hm.put("w", 1); // "w" 1 증가
hm.put("s", -1); // "s" 1 감소
hm.put("d", 10); // "d" 10 증가
hm.put("a", -10); // "a" 10 감소
// numLog 배열의 두 번째 요소부터 마지막 요소까지 반복합니다.
for(int i = 1; i < numLog.length; i++) {
int prev = numLog[i - 1]; // 이전 요소를 저장합니다.
int curr = numLog[i]; // 현재 요소를 저장합니다.
// HashMap의 각 엔트리를 반복합니다.
for(Map.Entry<String, Integer> entry : hm.entrySet()) {
int res = prev + entry.getValue(); // 이전 값에 이동 값을 더합니다.
// 계산된 결과가 현재 값과 같으면
if(res == curr) {
answer += entry.getKey(); // 해당 방향의 키를 결과 문자열에 추가합니다.
break; // 일치하는 경우 더 이상 반복할 필요가 없으므로 루프를 종료합니다.
}
}
}
return answer; // 최종 결과 문자열을 반환합니다.
}
}
Map.Entry는 Map의 내부 인터페이스로, 하나의 키-값 쌍을 나타낸다. Map의 entrySet() 메서드를 통해 Map.Entry 객체를 얻을 수 있다.
- Map의 entrySet() 메서드를 호출하여 Set<Map.Entry<K, V>>를 얻고, 이를 반복하여 각 엔트리에 접근한다.
- 각 Map.Entry 객체에서 getKey()와 getValue() 메서드를 사용하여 키와 값을 가져올 수 있다.
Share article