유난스런 개발 기록

[JAVA] Day-11 _ StringBuilder & StringBuilder (StringBuilder를 중심으로) 본문

개념정리/JAVA

[JAVA] Day-11 _ StringBuilder & StringBuilder (StringBuilder를 중심으로)

yourhwan 2023. 1. 23. 18:06

day-11

StringBuilder & StringBuffer


StringBuilder 와 StringBuffer를 사용하는 이유 ? 

 

  • String 클래스의 가장 큰 특징은 불변성(immutable) 이다.
  • 즉 String 클래스를 사용하여 메모리를 할당하면,
  • 새로운 문자열을 추가 할 때 기존의 메모리를 수정하는 것이 아니라
  • 아예 새로운 메모리를 할당하기 때문에 자원의 낭비가 일어난다.
  • 이러한 이유 때문에 문자열의 변경이 많다면 StringBuilder & StinrgBuffer를 사용하는 것이 효율적이다.

아래의 예시 코드와 같이 String을 사용한 경우를 확인해보자.

package my.day11.b.stringbuilder;

public class StringBuilder_main {

	public static void main(String[] args) {

		String name = "일순신";	// 메모리상에 name 1개 소모
		name += ",이순신";		// 메모리상에 name 1개 소모
		name += ",삼순신";		// 메모리상에 name 1개 소모
		name += ",사순신";		// 메모리상에 name 1개 소모
		name += ",오순신";		// 메모리상에 name 1개 소모
		name += ",육순신";		// 메모리상에 name 1개 소모
		name += ",칠순신";		// 메모리상에 name 1개 소모
		name += ",팔순신";		// 메모리상에 name 1개 소모
		name += ",구순신";		// 메모리상에 name 1개 소모

							 // 누적되어진 메모리상의 name은 9개 소모
                             
		System.out.println(name);
		// 일순신,이순신,삼순신,사순신,오순신,육순신,칠순신,팔순신,구순신
		
	}// end of main() -----------------

}

 

"일순신"이라는 문자열 변수를 String 으로 선언하고 수정을 거치게 된다면, 매번 새로운 메모리를 할당해준다.

일순신 ~ 구순신 까지 총 9번의 메모리 할당 과정을 거친다.

 

 

StringBuilder

package my.day11.b.stringbuilder;

public class StringBuilder_main {

	public static void main(String[] args) {
    
StringBuilder sb = new StringBuilder();
// StringBuilder 가 StringBuffer 보다 가볍고 빠르다.
// StringBuilder 는 단일 쓰레드에서만 사용가능하다.
// 단일 쓰레드 ==> 웹용

StringBuilder sb = new StringBuilder();
// StringBuilder 가 StringBuffer 보다 가볍고 빠르다.
// StringBuilder 는 단일 쓰레드에서만 사용가능하다.
// 단일 쓰레드 ==> 웹용
		
		
sb.append("일순신");		
sb.append(",이순신");
sb.append(",삼순신");
sb.append(",사순신");
sb.append(",오순신");
sb.append(",육순신");
sb.append(",칠순신");
sb.append(",팔순신");
sb.append(",구순신");
		
System.out.println(sb.toString());
// 일순신,이순신,삼순신,사순신,오순신,육순신,칠순신,팔순신,구순신
		
// StringBuilder sb 의 초기화 방법 1
sb.setLength(0); // 길이를 0 으로 하면 초기화 된다.
sb.append("초기화1");
System.out.println(sb.toString());
// 초기화1
		
// StringBuilder sb 의 초기화 방법 2
sb = new StringBuilder();
sb.append("초기화2");
System.out.println(sb.toString());
// 초기화2
		
System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
			
StringBuilder sb1 = new StringBuilder("Programming");
		
System.out.println("sb1.toString() => " + sb1.toString()); 
// 원래는 toString을 써야만 sb를 불러올 수 있지만 다른 방법도 있다.
// sb1.toString() => Programming
		
System.out.println("sb1 => " + sb1);
// sb1 => Programming
// 이것은 메소드가 오버라이딩 된 것이다. 나중에 배울 것
		
System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");

StringBuilder sb2 = sb1.replace(2, 6, "AAA");
// sb1 인 "Programming" 에서 2번째 index인 "o" 부터 6번째 index 인 "m" 앞까지를 지우고
// 즉, "ogra" 를 지우고 그 자리에 "AAA"를 넣어서 바꾸어라
// 그래서 sb1은 "PrAAAmming"로 변경된다.
// 이렇게 바꾼 결과물을 sb2에 넣어준다.
		
System.out.println("sb1 => " + sb1);
// sb1 => PrAAAmming
		
System.out.println("sb2 => " + sb2);
// sb2 => PrAAAmming
		
System.out.println("sb1.toString() => " + sb1.toString());
// sb1.toString() => PrAAAmming
		
System.out.println("sb2.toString() => " + sb2.toString());
// sb2.toString() => PrAAAmming

	
	}// end of main() -----------------

}

 

해당 코드와 내용은 수업 때 진행했던 예시다. 

하지만 애초에 "Thread(스레드)" 라는 개념을 알지 못했기 때문에 동작 원리를 이해하기보다

단순히 문자 그대로 받아들였다. 이해하지 못하면 그냥 그런가보다 하고 받아들이려는 습관이 여기서도 나왔다.

하지만 복습을 하면서 원리를 이해하고싶어 찾아봤다.

간단히 정리하자면 다음과 같다.

"싱글 스레드"의 경우 직렬적인 프로세스의 진행이 이루어지는 것을 의미하며,

"멀티 스레드"의 경우 병렬적인 프로세스의 진행이 이루어지는 것을 의미한다는 것이다.

 

더 이해하기 쉽게 비유를 하자면

장인 한명이 처음부터 끝까지 구두를 만드는 것 (싱글 스레드)

공장에서 구두의 밑창, 끈, 가죽의 공정 등 각 부분마다 분업이 이루어져 구두를 만드는 것 (멀티 스레드) 

둘의 차이와 장단점 등을 찾아보긴 했지만 지금 나의 수준에서 더 깊게 들어가는 것은 무리인 거 같다.

(기본 개념 이후로는 설명을 봐도 이해가 잘 안된다ㅋㅋㅋ...)

프로그래밍에 더 익숙해졌을 때 분명 짚고 넘어가야할 시기가 올테니 그 때  더 파보자 ^^

 

주석을 보면 StringBuilder가 StringBuffer보다 가볍고 빠르다고 적어두었는데,

아무래도 현재 JAVA웹개발 과정이라 CPU만을 활용한 작업이 대부분이기 떄문인 거 같다.

게임개발과 같이 좀 더 복잡하고 무거운 프로그래밍으로 간다면 멀티쓰레드가 대체로 더 효율적이겠다는 생각.

 

물론 웹개발을 할 떄도 StringBuffer를 사용하는 경우가 있을테지만, 이 부분도 나중이 되면 자연스레 알게되지 않을까?

StringBuilder의 초기화는 sb.append()를 통해 이루어지는데 괄호 안에 초기화할 값을 넣어주면 된다.

이 외에 delete() 메소드의 사용 등 몇가지 방법이 더 있지만 오늘 블로그에는 수업시간에 배운 내용만 정리하겠다.

초기화2의 경우 새로운 인스턴스를 생성해서 초기화 시켜주는 방법인데, 이것은 heap 영역에 새로운 메모리를 할당하기 때문에

효율이 좋지 않은듯하다.

 

해당 내용을 복습하면서 새로운 내용들도 많이 알게 되었고,

수업시간에 배운 내용 이외에 스스로 어떤 것들을 공부해야 할지 머릿속에 구상할 수 있었다.

요즘 공부하는게 힘들지만 그만큼 재미있어서 버티는 중이다 ^^...