append: StringBuilder 객체의 끝에 문자열을 추가한다.
StringBuilder sb = new StringBuilder("안녕");
sb.append("하세요"); // 를 실행하면 sb는 "안녕하세요"가 된다.
// sb = "안녕하세요"
insert: 지정된 인덱스 위치에 문자열을 삽입한다.
StringBuilder sb = new StringBuilder("안녕");
sb.insert(2, "하");
// 실행하면 sb의 "안녕" 문자열에서 두 번째 인덱스 위치에 "하"를 삽입해 "안하녕"이 된다.
toString: StringBuilder 객체를 String 객체로 변환한다.
StringBuilder sb = new StringBuilder("안녕");
sb.toString(); // 호출하면 StringBuilder 객체의 현재 문자열이 String 형태로 반환된다.
System.out.println("sb : " + sb.toString()); // sb : 안녕
substring: StringBuilder의 부분 문자열을 반환한다. sb.substring(1, 3);은 sb의 인덱스 1부터 3 전까지의 문자열을 반환한다.
StringBuilder sb = new StringBuilder("안녕하세요.");
String str = sb.substring(1, 3); // 녕하
replace: 문자열의 일부를 다른 문자열로 대체한다.
StringBuilder sb = new StringBuilder("안녕하세요.");
sb.replace(1, 3, "이"); // 안이세요
delete: 지정된 범위의 문자를 삭제한다.
StringBuilder sb = new StringBuilder("안녕하세요.");
sb.delete(1, 3); // 안세요
package com.mystudy.stringbuilder;
public class Ex01_StringBuffer {
public static void main(String[] args) {
// StringBuffer 클래스
StringBuffer sb = new StringBuffer("Hello");
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
System.out.println("--- String : 데이터 불변(immutable) ---");
String str = sb.toString();
System.out.println("str : " + str);
String str2 = str.concat(" 반갑습니다");
System.out.println("---------");
System.out.println("str : " + str);
System.out.println("str2 : " + str2);
System.out.println("--- StringBuffer : 데이터 변경 가능 ---");
System.out.println("sb : " + sb.toString());
StringBuffer sbTest = sb.append(" 반갑습니다.");
System.out.println("---------");
System.out.println("sb : " + sb.toString());
System.out.println("sbTest : " + sbTest.toString());
System.out.println("sb == sbTest : " + (sb == sbTest)); // true : 동일객체, 객체가 하나다!
sb.reverse();
System.out.println("reverse 후 sb : " + sb);
sb.reverse();
System.out.println("--- delete(), insert(), replace() ---");
// Hello Java!! 반갑습니다~~
System.out.println("sb delete(0, 6) : " + sb.delete(0, 6));
System.out.println("sb : " + sb.toString());
System.out.println("sb.insert(0, \"Hello \") : " + sb.insert(0, "Hello "));
System.out.println(sb.replace(0, 5, "Hi"));
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
sb.append(" 새로운 StringBuffer 학습중~~~ 재미있나요????"); // 공간이 자동으로 만들어진다!
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
System.out.println("-------------------------------");
StringBuffer sb2 = new StringBuffer(100);
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
sb2.append("안녕하세요").append(" 반갑습니다!!!");
System.out.println("sb2 : " + sb2.toString());
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
System.out.println("--- trimToSize() 실행 ---");
System.out.println("--- setLength(5)적용 ---");
sb2.setLength(5); // 5개만 남기고 지워짐
// sb2.delete(5, sb2.length()); // 앞에 5개 남기고 모두 삭제
System.out.println("sb2 : " + sb2.toString());
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
}
}
StringBuffer sb = new StringBuffer("Hello");
여기서 StringBuffer 객체 sb가 "Hello"라는 문자열로 초기화된다.
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
toString()은 StringBuffer 객체를 문자열로 변환한다.
length()는 현재 문자열의 길이를 반환한다.
capacity()는 StringBuffer 객체가 담을 수 있는 전체 용량을 반환한다.
String str = sb.toString();
String str2 = str.concat(" 반갑습니다");
String 클래스는 불변(immutable)이므로, concat 메서드를 사용해도 원본 문자열 str은 변경되지 않고 새로운 문자열 str2가 생성된다.
StringBuffer sbTest = sb.append(" 반갑습니다.");
StringBuffer는 가변(mutable)dl다. append 메서드를 사용하면 원본 StringBuffer 객체 sb에 문자열이 추가되며, 이 때 새로운 객체가 생성되지 않는다. sb와 sbTest는 동일한 객체를 참조한다. (sb == sbTest 결과는 true).
이 코드는 StringBuffer를 통해 문자열을 가변적으로 다루는 방법과 String과의 주요 차이점을 잘 보여준다. StringBuilder를 사용할 때도 이와 유사한 방식으로 작업할 수 있으나, 스레드 안전성 측면에서는 차이가 있음을 유념해야 한다.
StringBuffer에서 capacity()는 내부적으로 할당된 버퍼의 크기를 나타낸다. 만약 StringBuffer의 capacity 용량을 초과하는 문자열을 추가하려고 하면, StringBuffer는 자동으로 내부 버퍼의 크기를 확장한다.
이 과정은 다음과 같이 이루어진다.
이러한 방식으로 StringBuffer는 가변적인 크기를 가질 수 있으며, 사용자가 문자열을 추가할 때마다 자동으로 크기를 조절한다. 이 메커니즘은 메모리 사용량과 성능에 영향을 줄 수 있으므로, 애플리케이션에서 큰 문자열을 다룰 때는 초기에 충분한 크기의 StringBuffer를 생성하는 것이 좋다.
package com.mystudy.stringbuilder;
public class Ex02_StringBuilder {
public static void main(String[] args) {
// StringBuilder 클래스 : StringBuffer와 기능(메소드) 동일
StringBuilder sb = new StringBuilder("Hello");
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
System.out.println("--- String : 데이터 불변(immutable) ---");
String str = sb.toString();
System.out.println("str : " + str);
String str2 = str.concat(" 반갑습니다");
System.out.println("---------");
System.out.println("str : " + str);
System.out.println("str2 : " + str2);
System.out.println("--- StringBuilder : 데이터 변경 가능 ---");
System.out.println("sb : " + sb.toString());
StringBuilder sbTest = sb.append(" 반갑습니다.");
System.out.println("---------");
System.out.println("sb : " + sb.toString());
System.out.println("sbTest : " + sbTest.toString());
System.out.println("sb == sbTest : " + (sb == sbTest)); // true : 동일객체, 객체가 하나다!
sb.reverse();
System.out.println("reverse 후 sb : " + sb);
sb.reverse();
System.out.println("--- delete(), insert(), replace() ---");
// Hello Java!! 반갑습니다~~
System.out.println("sb delete(0, 6) : " + sb.delete(0, 6));
System.out.println("sb : " + sb.toString());
System.out.println("sb.insert(0, \"Hello \") : " + sb.insert(0, "Hello "));
System.out.println(sb.replace(0, 5, "Hi"));
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
sb.append(" 새로운 StringBuilder 학습중~~~ 재미있나요????"); // 공간이 자동으로 만들어진다!
System.out.println("sb : " + sb.toString());
System.out.println("sb.length() : " + sb.length());
System.out.println("sb.capacity() : " + sb.capacity());
System.out.println("-------------------------------");
StringBuilder sb2 = new StringBuilder(100);
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
sb2.append("안녕하세요").append(" 반갑습니다!!!");
System.out.println("sb2 : " + sb2.toString());
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
System.out.println("--- trimToSize() 실행 ---");
System.out.println("--- setLength(5)적용 ---");
sb2.setLength(5); // 5개만 남기고 지워짐
// sb2.delete(5, sb2.length()); // 앞에 5개 남기고 모두 삭제
System.out.println("sb2 : " + sb2.toString());
System.out.println("sb2.length() : " + sb2.length());
System.out.println("sb2.capacity() : " + sb2.capacity());
}
}
먼저 StringBuffer와 StringBuilder의 기본적인 차이점을 이해해야 한다. StringBuffer는 동기화가 지원되어 멀티스레드 환경에서 안전하다는 점에서 StringBuilder와 다르다. 반면, StringBuilder는 동기화를 지원하지 않아 StringBuffer보다 빠르지만, 단일 스레드 환경에서 사용하는 것이 적합하다.
StringTokenizer 클래스는 Java에서 문자열을 특정 구분자를 기준으로 여러 개의 토큰으로 분리할 때 사용된다. 이 클래스는 java.util 패키지에 포함되어 있으며, 문자열을 토큰화하는 간단하고 편리한 방법을 제공한다.
StringTokenizer의 주요 특징과 사용 방법은 다음과 같다.
StringTokenizer(String str): 기본 구분자(공백, 탭, 개행 문자 등)를 사용하여 문자열 str을 토큰화한다.StringTokenizer(String str, String delim): 사용자가 지정한 구분자 delim을 사용하여 문자열 str을 토큰화한다.StringTokenizer(String str, String delim, boolean returnDelims): 사용자가 지정한 구분자 delim을 사용하며, returnDelims가 true인 경우 구분자도 토큰으로 간주한다.hasMoreTokens(): 더 이상 토큰이 있는지 확인합니다. 더 이상 토큰이 없을 경우 false를 반환한다.nextToken(): 다음 토큰을 반환한다.countTokens(): 남아 있는 토큰의 수를 반환한다.StringTokenizer st = new StringTokenizer("안녕하세요, Java 세계로 오신 것을 환영합니다", " ,"); // 공백과 쉼표를 구분자로 사용
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
//Java
//세계로
//오신
//것을
//환영합니다
StringTokenizer는 문자열을 구분자로 쉽게 분리할 수 있게 해주지만, split() 메서드와 달리 정규 표현식을 사용할 수 없다. 따라서 복잡한 문자열 분리가 필요한 경우에는 String 클래스의 split() 메서드를 사용하는 것이 더 유연하고 강력한 방법이 될 수 있다.
package com.mystudy.stringbuilder;
import java.util.StringTokenizer;
public class Ex03_StringTokenizer {
public static void main(String[] args) {
// String 클래스의 split() vs StringTokenizer 클래스
System.out.println("--- String split() ---");
String str = "사과,배,복숨아,,포도";
System.out.println("str : " + str.toString());
String[] strSplit = str.split(",");
System.out.println("strSplit.length : " + strSplit.length);
System.out.println("--- str.split(\",\") 실행결과 배열 ---");
for (int i = 0; i < strSplit.length; i++) {
System.out.println(i + ":-" + strSplit[i] + "-");
}
System.out.println();
System.out.println("--- 개선된 for문으로 ---");
for (String str2 : strSplit) {
System.out.println("-" + str2 + "-");
}
System.out.println();
System.out.println("=== StringTokenizer ===");
str = "사과,배,복숨아,,포도";
System.out.println("str : " + str);
StringTokenizer strToken = new StringTokenizer(str, ",");
System.out.println("strToken : " + strToken);
System.out.println("strToken.countTokens() : " + strToken.countTokens());
while (strToken.hasMoreTokens()) {
String token = strToken.nextToken();
System.out.println("-" + token + "-");
}
System.out.println("저장된 토큰 갯수 : " + strToken.countTokens());
// strToken.nextToken(); // NoSuchElementException 오류 발생(데이터가 없을 떄)
System.out.println("-------------------------");
System.out.println("(실습) 토큰 데이터를 for문으로 출력 --------------");
str = "사과,배,복숨아,,포도";
StringTokenizer strToken1 = new StringTokenizer(str, ",");
int j = strToken1.countTokens();
for (int i = 0; i < j; i++) {
String token1 = strToken1.nextToken();
System.out.println("-" + token1 + "-");
}
}
}
--- String split() ---
str : 사과,배,복숨아,,포도
strSplit.length : 5
--- str.split(",") 실행결과 배열 ---
0:-사과-
1:-배-
2:-복숨아-
3:--
4:-포도-
--- 개선된 for문으로 ---
-사과-
-배-
-복숨아-
--
-포도-
=== StringTokenizer ===
str : 사과,배,복숨아,,포도
strToken : java.util.StringTokenizer@15db9742
strToken.countTokens() : 4
-사과-
-배-
-복숨아-
-포도-
저장된 토큰 갯수 : 0
-------------------------
(실습) 토큰 데이터를 for문으로 출력 --------------
-사과-
-배-
-복숨아-
-포도-
위 코드에서는 String 클래스의 split() 메서드와 java.util.StringTokenizer 클래스를 사용하여 문자열을 분리하는 방법을 비교하고 있다. 각각의 방법을 사용하여 문자열 "사과,배,복숨아,,포도"를 쉼표(,)를 기준으로 분리하고 있다.
StringTokenizer를 사용하는 경우, 토큰이 더 이상 없을 때 nextToken()을 호출하면 NoSuchElementException 오류가 발생한다. 이를 방지하기 위해 hasMoreTokens() 메서드로 토큰의 존재 여부를 확인한다.