String, StringBuffer, StringBuilder

jaehun_dev·2022년 12월 27일
0

Java

목록 보기
2/6

String 클래스

  • String 클래스는 char[] 데이터와 관련 메서드로 구성된다.
  • 내용을 변경할 수 없는 불변(immutable) 클래스다. 따라서 만약 String을 편집하거나 두 개를 합치는 등을 통해 문자열이 달라지면, 새로운 객체가 생성된다.
  • 즉 문자열 결합을 할 때마다 계속 새로운 문자열 객체가 생성된다. 따라서 성능이 저하된다.
    ✅ 문자열의 결합 / 변경이 잦을 때 해결책: StringBuffer

String의 비교

String을 생성하는 방법은 다음 두가지가 있다.

  • String str1 = "abc";
    String str2 = "abc";
  • String str3 = new String("abc");
    String str4 = new String("abc");

첫번째 방식은 str1과 str2가 가리키는 객체가 동일하다. 즉 둘 모두 동일한 주소의 "abc"라는 문자열 리터럴을 공유한다.
두번째 방식은 새로운 String 인스턴스를 생성한다. 즉 str3와 str4의 문자열 값 자체는 동일하지만, 두 객체가 가리키는 주소값은 다르다.
String 클래스는 불변이기 때문에, 첫번째 방식으로 두 개 이상의 String 클래스가 동일한 문자열 리터럴을 공유하더라도 큰 문제는 없다.
이에 따른 차이는 "==" 연산에서도 나타난다.

  • 첫번째 방식으로 생성한 str1과 str2는 주소값 역시 같다. 따라서 == 연산의 결과는 true가 된다.
  • 두번째 방식으로 생성한 str3와 str4는 그 값은 같지만 주소값이 다르다. 따라서 == 연산의 결과는 false가 된다.

따라서 String 클래스에서 주소값의 비교가 아닌 실제 문자열 값을 비교하고 싶다면, == 보다는 "equals" 메소드를 사용해야 한다.

	System.out.println(str1 == str2);	//true
	System.out.println(str1.equals(str2));	//true
    System.out.println(str3 == str4);	//false
	System.out.println(str3.equals(str4));	//true        

"compareTo" 메소드 역시 문자열의 비교에 사용할 수 있다. 해당 메소드는, 두 문자열이 같다면 0, 문자열이 사전순으로 더 앞선다면 -1, 뒤에 있다면 1을 반환한다.

	System.out.println("aaa".compareTo("aaa"));	//0
    System.out.println("aaa".compareTo("bbb"));	//-1
    System.out.println("bbb".compareTo("aaa"));	//1

StringBuffer 클래스

  • StringBuffer 클래스 역시 char[]형 데이터를 가진다.
  • 그러나 String과 달리 내용 변경이 가능하다. (mutable)
    StringBuffer 역시 고정된 크기의 배열에 문자들이 할당되는 형태다. 따라서 mutable이지만 만약 모든 배열이 다 찬다면, 새로운 배열 공간을 할당하고 기존의 데이터를 옮긴 후 참조를 변경하는 과정이 요구된다. 이는 곧 성능의 오버헤드이기 때문에, 처음 StringBuffer 생성 시 문자열의 길이를 고려한 적절한 크기 할당이 요구된다.

StringBuffer의 변경

앞서 설명했듯 StringBuffer는 내용 변경이 가능하다.

  • append()는 지정된 내용을 StringBuffer에 추가 후 StringBuffer(즉 자기자신)의 참조를 반환한다.
StringBuffer sb = new StringBuffer("abc");	//sb == "abc"
sb.append("123");	//sb == "abc123"
StringBuffer sb2 = sb.append("ZZ");	//sb == sb2 == "abc123ZZ"

StringBuffer의 비교

equals가 오버라이딩 되어 있는 String과 달리, StringBuffer는 equals가 오버라이딩 되어 있지 않다. 즉 equals가 문자열의 내용으로 비교하지 않고 주소값으로 비교를 한다. 따라서 두 개의 StringBuffer의 문자열이 동일한지를 비교하기 위해서는 equals를 쓰기 전에 String으로 변환하는 작업이 요구된다.

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb == sb2);	//주소 비교 -> false;
System.out.println(sb.equals(sb2));	//주소 비교 -> false;
String s = sb.toString();
String s2 = sb2.toString();
System.out.println(s.equals(s2));	//값 비교 -> true;

StringBuilder

StringBuffer는 동기화되어 있기 때문에 멀티스레드 환경에서 안전하다. 그러나 동기화는 곧 성능 저하이기 때문에 싱글스레드 환경에서는 동기화가 없는 StringBuilder를 사용하면 더 나은 성능이 가능하다.

profile
취업준비생/코딩&프로젝트 같이 하실분 연락주세요

0개의 댓글