[기억을 되돌리며#2] 문자열을 붙여주는 StringBuilder
Java Output Formatting
Input Format
Every line of input will contain a String followed by an integer.
Each String will have a maximum of alphabetic characters, and each integer will be in the inclusive range from to .
Output Format
In each line of output there should be two columns:
The first column contains the String and is left justified using exactly characters.
The second column contains the integer, expressed in exactly digits; if the original input has less than three digits, you must pad your output's leading digits with zeroes.
Sample Input
java 100
cpp 65
python 50
Sample Output
================================
java 100
cpp 065
python 050
================================
저번과 같이 문제는 단순하다.
첫 번째 컬럼값은 알파벳이 들어가는데 15자까지 들어간다. 만약 15자리보다 작으면 공백으로 채워준다.
두 번째 컬럼값은 숫자가 들어가는데 3자리까지 들어간다. 만약 3자리보다 작으면 0으로 채워준다.
내가 생각한 로직은 입력받은 값에서 ' '을 split 시켜서 첫 번째 문자는 15를 뺀 만큼 반복해서 공백을 넣어주고,
두 번째 문자는 3을 뺀 만큼 반복해서 0을 채워주기로 했다.
자 여기서 문자를 채울 때 String끼리 + 연산을 해서 채워 넣어줄 수도 있고 아니면 StringBuilder라는 놈을 이용해서 문자를 채울 수 있다. 둘 다 문자를 똑같이 채워주는 것 같지만 실제로 내부 동작을 보면 다르다.
결론적으로 말하자면 String끼리 + 연산을 하게 되면 내부적으로 StringBuilder객체를 새로 생성 후 append() 연산을 수행 후 최종적으로 toString()를 통해 문자를 리턴한다. 즉, + 연산만큼 '객체 생성 + append() 연산 + toString() 연산'을 반복해서 수행하기 때문에 메모리를 비효율적이게 사용된다.
다만, 반복 처리가 적을 경우에 한해서는 +써도 성능에 크게 무리는 안 간다.
StringBuilder를 통해 사용할 경우 하나의 객체를 통해서 문자열을 가변적으로 추가, 삭제가 가능하다. 이놈은 하나의 메모리 주소를 사용해서 문자를 가변적으로 처리하기 때문에 잦은 반복문을 통해 문자를 처리해야 할 경우 String의 + 연산보다 더 효율적이다.
자매품으로 StringBuffer가 있는데 차이점은 동기화를 제공해주냐 안 해주냐 차이이다.
StringBuffere는 동기화를 제공하지만 그만큼 속도가 느리다.
StringBuilder는 동기를 제공하지 않아 멀티 스레드 환경에서 취약하지만 그만큼 속도가 빠르다.
import java.util.Scanner;
import java.io.*;
public class Solution {
public static void main(String[] args) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] temp = null;
String result = null;
int size = 0;
System.out.println("================================");
for(int i=0;i<3;i++)
{
temp = br.readLine().split(" ");
size = 15 - temp[0].length();
sb.append(temp[0]);
for (int j = 0; j < size; j++) {
sb.append(" ");
}
size = 3 - temp[1].length();
for (int k = 0; k < size; k++) {
sb.append("0");
}
sb.append(temp[1]);
System.out.println(sb.toString());
sb.setLength(0);
}
System.out.println("================================");
}
}
아 참고로 이번 포스팅을 쓴 이유는 StringBuilder의 내용을 초기화해야 하는데 얘가 지원하는 메서드가 clear()였는지, setSize(Integer)였는지 헷갈렸다가 결국 3번의 Exception이 발생돼서 작성하게 되었다. StringBuilder의 내용을 초기화할 땐 setLength(Integer)! 까먹지 말도록 하자.
이놈의 IDE 자동완성 때문에 헷갈리는 게 이만저만이 아니다. 온라인에서 제공해주는 환경에선 자동완성이란 기능이 없으니 내가 무슨 메소드를 써야하는지 순간적으로 파악을 해야 하는데 아직까지 연습이 부족한 것 같다. 언젠가는 자동완성 없이도 내가 원하는 함수를 바로바로 가져다 쓸 수 있도록 잘 암기해두자.