본문 바로가기

Coding Language/Java

[기억을 되돌리며#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 자동완성 때문에 헷갈리는 게 이만저만이 아니다. 온라인에서 제공해주는 환경에선 자동완성이란 기능이 없으니 내가 무슨 메소드를 써야하는지 순간적으로 파악을 해야 하는데 아직까지 연습이 부족한 것 같다. 언젠가는 자동완성 없이도 내가 원하는 함수를 바로바로 가져다 쓸 수 있도록 잘 암기해두자.