โ ์๋ฐ String / StringBuffer / StringBuilder ์ฐจ์ด์ & ์ฑ๋ฅ ๋น๊ต
์๋ฐ์์๋ ๋ํ์ ์ผ๋ก ๋ฌธ์์ด์ ๋ค๋ฃจ๋ ์๋ฃํ ํด๋์ค๋ก String, StringBuffer, StringBuilder ๋ผ๋ 3๊ฐ์ง ์๋ฃํ์ ์ง์ํ๋ค.
์ 3๊ฐ์ง ํด๋์ค ์๋ฃํ์ ๋ชจ๋ ๋ฌธ์์ด์ ๋ค๋ฃจ๋๋ฐ ์์ด ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋์ง๋ง, ์ฌ์ฉ ๋ชฉ์ ์ ๋ฐ๋ผ ์ฐ์์๊ฐ ๋ง์ด ๋ฌ๋ผ์ง๊ฒ ๋๋ค.
์ด๋ฒ ์๊ฐ์๋ String, StringBuffer, StringBuilder ํด๋์ค ์ฐจ์ด์ ์ ์์๋ณด๊ณ , ์ด 3๊ฐ์ง ์ค ์ด๋ ์ํฉ์์ ์ด๋ ์๋ฃํ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ด์์ ์ด๊ณ ์ฑ๋ฅ์ ์ผ๋ก๋ ์ด๋๊ฒ์ด ๋ ์ข์์ง ์ด์ ๋ฆฌ ํด๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด์.
StringBuffer / StringBuilder ํด๋์ค
StringBuffer / StringBuilder ํด๋์ค๋ ๋ฌธ์์ด์ ์ฐ์ฐ(์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝ) ํ ๋ ์ฃผ๋ก ์ฌ์ฉํ๋ ์๋ฃํ์ด๋ค.
๋ฌผ๋ก String ์๋ฃํ๋ง ์ผ๋ก๋, + ์ฐ์ฐ์ด๋ concat() ๋ฉ์๋๋ก ๋ฌธ์์ด์ ์ด์ด๋ถ์ผ์ ์๋ค.
ํ์ง๋ง ๋ง์ (+) ์ฐ์ฐ์๋ฅผ ์ด์ฉํด String ์ธ์คํด์ค์ ๋ฌธ์์ด์ ๊ฒฐํฉํ๋ฉด, ๋ด์ฉ์ด ํฉ์ณ์ง ์๋ก์ด String ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋์ด, ๋ฐ๋ผ์ ๋ฌธ์์ด์ ๋ง์ด ๊ฒฐํฉํ๋ฉด ๊ฒฐํฉํ ์๋ก ๊ณต๊ฐ์ ๋ญ๋น๋ฟ๋ง ์๋๋ผ ์๋ ๋ํ ๋งค์ฐ ๋๋ ค์ง๊ฒ ๋๋ค๋ ๋จ์ ์ด ์๋ค.
String result = "";
result += "hello";
result += " ";
result += "jump to java";
System.out.println(result); // hello jump to java
// → ์ฌํํ์ง๋ง ์ฐ์ฐ ์๋๊ฐ ๋๋ฆฌ๋ค๋ ๋จ์ ์ด ์๋ค
๊ทธ๋์ ์๋ฐ์์๋ ์ด๋ฌํ ๋ฌธ์์ด ์ฐ์ฐ์ ์ ์ฉ์ผ๋ก ํ๋ ์๋ฃํ์ ๋ฐ๋ก ๋ง๋ค์ด ์ ๊ณตํด์ฃผ๋๋ฐ, StringBuffer ํด๋์ค๋ ๋ด๋ถ์ ์ผ๋ก ๋ฒํผ(buffer)๋ผ๊ณ ํ๋ ๋ ๋ฆฝ์ ์ธ ๊ณต๊ฐ์ ๊ฐ์ง๊ฒ ๋์ด, ๋ฌธ์์ด์ ๋ฐ๋ก ์ถ๊ฐํ ์ ์์ด ๊ณต๊ฐ์ ๋ญ๋น๋ ์์ผ๋ฉฐ ๋ฌธ์์ด ์ฐ์ฐ ์๋๋ ๋งค์ฐ ๋น ๋ฅด๋ค๋ ํน์ง์ด ์๋ค.
StringBuffer sb = new StringBuffer(); // StringBuffer ๊ฐ์ฒด sb ์์ฑ
sb.append("hello");
sb.append(" ");
sb.append("jump to java");
String result = sb.toString();
System.out.println(result); // hello jump to java
// → + ์ฐ์ฐ๋ณด๋ค๋ ๋ณต์กํด ๋ณด์ด์ง๋ง ์ฐ์ฐ ์๋๊ฐ ๋น ๋ฅด๋ค๋ ์ฅ์ ์ด ์๋ค
StringBuffer์ ๋น์ทํ ์๋ฃํ์ผ๋ก StringBuilder ์๋ฃํ์ด ์๋ค.
StringBuilder ์ฌ์ฉ๋ฒ์ StringBuffer์ ๋์ผํ๋ค.
๋ค์์ ์์ธํ ๋ค๋ฃจ๊ฒ ์ง๋ง StringBuffer์ StringBuilder์ ์ฐจ์ด๋, StringBuffer๋ ๋ฉํฐ ์ค๋ ๋ ์๊ฒฝ์์ ์์ ํ๋ค๋ ์ฅ์ ์ด ์๊ณ , StringBuilder๋ ๋ฌธ์์ด ํ์ฑ ์ฑ๋ฅ์ด ๊ฐ์ฅ ์ฐ์ํ๋ค๋ ์ฅ์ ์ด ์๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก StringBuffer์ ๋ฒํผ(๋ฐ์ดํฐ ๊ณต๊ฐ) ํฌ๊ธฐ์ ๊ธฐ๋ณธ๊ฐ์ 16๊ฐ์ ๋ฌธ์๋ฅผ ์ ์ฅํ ์ ์๋ ํฌ๊ธฐ์ด๋ฉฐ, ์์ฑ์๋ฅผ ํตํด ๊ทธ ํฌ๊ธฐ๋ฅผ ๋ณ๋๋ก ์ค์ ํ ์๋ ์๋ค.
๋ง์ผ ๋ฌธ์์ด ์ฐ์ฐ์ค์ ํ ๋น๋ ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ๋๊ฒ ๋๋ฉด ์๋์ผ๋ก ๋ฒํผ๋ฅผ ์ฆ๊ฐ ์ํค๋ ๊ฑฑ์ ์ํด๋ ๋๋ค. ๋ค๋ง, ํจ์จ์ด ๋จ์ด์ง ์ ์์ผ๋ฏ๋ก ๋ฒํผ์ ํฌ๊ธฐ๋ ๋๋ํ๊ฒ ์ก๋ ๊ฒ์ด ์ข๋ค.
StringBuffer sb = new StringBuffer(); // ๊ธฐ๋ณธ 16 ๋ฒํผ ํฌ๊ธฐ๋ก ์์ฑ
// sb.capacity() - StringBuffer ๋ณ์์ ๋ฐฐ์ด ์ฉ๋์ ํฌ๊ธฐ ๋ฐํ
System.out.println(sb.capacity()); // 16
sb.append("1111111111111111111111111111111111111111"); // 40๊ธธ์ด์ ๋ฌธ์์ด์ append
System.out.println(sb.capacity()); // 40 (์ถ๊ฐ๋ ๋ฌธ์์ด ๊ธธ์ด๋งํผ ๋์ด๋จ)
StringBuffer ๋ด์ฅ ๋ฉ์๋
String str = "abcdefg";
StringBuffer sb = new StringBuffer(str); // String -> StringBuffer
System.out.println("์ฒ์ ์ํ : " + sb); // ์ฒ์์ํ : abcdefg
System.out.println("๋ฌธ์์ด String ๋ณํ : " + sb.toString()); // StringBuffer๋ฅผ String์ผ๋ก ๋ณํํ๊ธฐ
System.out.println("๋ฌธ์์ด ์ถ์ถ : " + sb.substring(2,4)); // ๋ฌธ์์ด ์ถ์ถํ๊ธฐ
System.out.println("๋ฌธ์์ด ์ถ๊ฐ : " + sb.insert(2,"์ถ๊ฐ")); // ๋ฌธ์์ด ์ถ๊ฐํ๊ธฐ
System.out.println("๋ฌธ์์ด ์ญ์ : " + sb.delete(2,4)); // ๋ฌธ์์ด ์ญ์ ํ๊ธฐ
System.out.println("๋ฌธ์์ด ์ฐ๊ฒฐ : " + sb.append("hijk")); // ๋ฌธ์์ด ๋ถ์ด๊ธฐ
System.out.println("๋ฌธ์์ด์ ๊ธธ์ด : " + sb.length()); // ๋ฌธ์์ด์ ๊ธธ์ด๊ตฌํ๊ธฐ
System.out.println("์ฉ๋์ ํฌ๊ธฐ : " + sb.capacity()); // ์ฉ๋์ ํฌ๊ธฐ ๊ตฌํ๊ธฐ
System.out.println("๋ฌธ์์ด ์ญ์ ๋ณ๊ฒฝ : " + sb.reverse()); // ๋ฌธ์์ด ๋ค์ง๊ธฐ
System.out.println("๋ง์ง๋ง ์ํ : " + sb); // ๋ง์ง๋ง์ํ : kjihgfedcba
๋ฉ์๋ | ์ค ๋ช |
StringBuffer( ) | ๋ฒํผ์ ๊ธธ์ด๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด ํฌ๊ธฐ๊ฐ 16 ์ธ ๋ฒํผ๋ฅผ ์์ฑ |
StringBuffer(int length) | length ๊ธธ์ด๋ฅผ ๊ฐ์ง StringBuffer ํด๋์ค์ ์ธ์คํด์ค(buffer)๋ฅผ ์์ฑ |
StringBuffer(String str) | ์ง์ ํ ๋ฌธ์์ด( str )์ ๊ธธ์ด๋ณด๋ค 16 ๋งํผ ๋ ํฐ ๋ฒํผ๋ฅผ ์์ฑ |
StringBuffer append(boolean b) StringBuffer append(char c) StringBuffer append(char[ ] str) StringBuffer append(double d) StringBuffer append(float f) StringBuffer append(int i) StringBuffer append(long l) StringBuffer append(Object obj) StringBuffer append(String str) |
๋งค๊ฐ๋ณ์๋ก ์ ๋ ฅ๋ ๊ฐ์ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ StringBuffer ์ธ์คํด์ค๊ฐ ์ ์ฅํ๊ณ ์๋ ๋ฌธ์์ด์ ๋ค์ ๋ง๋ถ์ |
int capacity( ) | StringBuffer ์ธ์คํด์ค์ ๋ฒํผํฌ๊ธฐ ๋ฐํ (์๋ฃํ์ ํ ๋น๋ ํฌ๊ธฐ๋ฅผ ๋ฐํ) |
int length( ) | StringBuffer ์ธ์คํด์ค์ ์ ์ฅ๋ ๋ฌธ์์ด์ ๊ธธ์ด ๋ฐํ (๋ฒํผ์ ๋ด๊ธด ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐํ) |
char charAt(int index) | ์ง์ ๋ ์์น( index )์ ์๋ ๋ฌธ์๋ฅผ ๋ฐํ |
StringBuffer delete(int start, int end) | ์์์์น( start )๋ถํฐ ๋ ์์น( end )์ฌ์ด์ ์๋ ๋ฌธ์๋ฅผ ์ ๊ฑฐ ๋จ, end ์์น์ ๋ฌธ์๋ ์ ์ธ(start <= x < end) |
StringBuffer deleteCharAt(int index) | ์ง์ ๋ ์์น( index )์ ๋ฌธ์๋ฅผ ์ ๊ฑฐ |
StringBuffer insert(int pos, boolean b) StringBuffer insert(int pos, char c) StringBuffer insert(int pos, char[ ] str) StringBuffer insert(int pos, doule d) StringBuffer insert(int pos, float f) StringBuffer insert(int pos, int i) StringBuffer insert(int pos, long l) StringBuffer insert(int pos, Object obj) StringBuffer insert(int pos, String str) |
๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ ๊ฐ์ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ์ง์ ๋ ์์น( pos )์ ์ถ๊ฐ ( pos ๋ 0๋ถํฐ ์์) |
StringBuffer replace(int start, int end, String str) | ์ง์ ๋ ๋ฒ์( start ~ end )์ ๋ฌธ์๋ค์ ์ฃผ์ด์ง ๋ฌธ์์ด๋ก ๋ฐ๊พผ๋ค. ๋จ, end ์ ์์น๋ ๋ฒ์์ ํฌํจ๋์ง X (start <= x < end) |
StringBuffer reverse( ) | StringBuffer ์ธ์คํด์ค์ ์ ์ฅ๋์ด ์๋ ๋ฌธ์์ด์ ์์๋ฅผ ๊ฑฐ๊พธ๋ก ๋์ด |
void setCharAt(int index, char ch) | ์ง์ ๋ ์์น( index )์ ๋ฌธ์๋ฅผ ์ฃผ์ด์ง ๋ฌธ์( ch )๋ก ๋ฐ๊พผ๋ค. |
void setLength(int newLength) | ์ง์ ๋ ๊ธธ์ด๋ก ๋ฌธ์์ด์ ๊ธธ์ด๋ฅผ ๋ณ๊ฒฝ ๊ธธ์ด๋ฅผ ๋๋ฆฌ๋ ๊ฒฝ์ฐ์๋ ๋๋จธ์ง ๋น๊ณต๊ฐ๋ค์ ๋๋ฌธ์( \u0000 )๋ก ์ฑ์ด๋ค. |
String toString( ) | StringBuffer ์ธ์คํด์ค์ ๋ฌธ์์ด์ String ์ผ๋ก ๋ณํ |
String substring(int start) String substring(int start, int end) |
์ง์ ๋ ๋ฒ์ ๋ด์ ๋ฌธ์์ด์ String ์ผ๋ก ๋ฝ์์ ๋ฐํ (์์์์น( start )๋ง ์ง์ ํ๋ฉด ์์์์น๋ถํฐ ๋๊น์ง ๋ฝ์์ ๋ฐํ) |
StringBuffer ํด๋์ค ๋ฉ์๋์ StringBuilder ํด๋์ค ๋ฉ์๋ ์ฌ์ฉ๋ฒ์ ๋์ผํ๋ค.
String vs (StringBuffer, StringBuilder) ๋น๊ต
๋ฌธ์์ด ์๋ฃํ์ ๋ถ๋ณ๊ณผ ๊ฐ๋ณ
String์ ๋ถ๋ณ
๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฐ์์๋ String ๊ฐ์ฒด์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
์ด๋ ํ๋ฒ ํ ๋น๋ ๊ณต๊ฐ์ด ๋ณํ์ง ์๋๋ค๊ณ ํด์ '๋ถ๋ณ(immutable)' ์๋ฃํ ์ด๋ผ๊ณ ๋ถ๋ฆฌ์ด๋ค. ๊ทธ๋์ ์ด๊ธฐ๊ณต๊ฐ๊ณผ ๋ค๋ฅธ ๊ฐ์ ๋ํ ์ฐ์ฐ์์ ๋ง์ ์๊ฐ๊ณผ ์์์ ์ฌ์ฉํ๊ฒ ๋๋ค๋ ํน์ง์ด ์๋ค.
์ค์ ๋ก String ๊ฐ์ฒด์ ๋ด๋ถ ๊ตฌ์ฑ ์์๋ฅผ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋์ด ์๋ค.
์ธ์คํด์ค ์์ฑ ์ ์์ฑ์์ ๋งค๊ฐ๋ณ์๋ก ์ ๋ ฅ๋ฐ๋ ๋ฌธ์์ด์ ์ด value ๋ผ๋ ์ธ์คํด์ค ๋ณ์์ ๋ฌธ์ํ ๋ฐฐ์ด๋ก ์ ์ฅ๋๊ฒ ๋๋ค. ์ด value ๋ผ๋ ๋ณ์๋ ์์(final)ํ์ด๋ ๊ฐ์ ๋ฐ๊พธ์ง ๋ชปํ๋ ๊ฒ์ด๋ค.
public final class String implements java.io.Serializable, Comparable {
private final byte[] value;
}
jdk 8 ๊น์ง๋ String ๊ฐ์ฒด์ ๊ฐ์ char[] ๋ฐฐ์ด๋ก ๊ตฌ์ฑ๋์ด์ ธ ์์ง๋ง, jdk 9๋ถํฐ ๊ธฐ์กด char[]์์ byte[]์ ์ฌ์ฉํ์ฌ String Compacting์ ํตํ ์ฑ๋ฅ ๋ฐ heap ๊ณต๊ฐ ํจ์จ(2byte -> 1byte)์ ๋์ด๋๋ก ์์ ๋์๋ค.
์๋ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ณ์ a ๊ฐ ์ฐธ์กฐํ๋ ๋ฉ๋ชจ๋ฆฌ์ "Hello" ๋ผ๋ ๊ฐ์ "World" ๋ผ๋ ๋ฌธ์์ด์ ๋ํด์ String ๊ฐ์ฒด์ ์์ฒด์ ๊ฐ์ ์
๋ฐ์ดํธ ์ํจ ๊ฒ์ผ๋ก ๋ณด์ผ์ ์๋ค.
ํ์ง๋ง ์ค์ ๋ก๋ ๋ฉ๋ชจ๋ฆฌ์ ์๋ก "Hello World" ๊ฐ์ ์ ์ฅํ ์์ญ์ ๋ฐ๋ก ๋ง๋ค๊ณ ๋ณ์ a ๋ฅผ ๋ค์ ์ฐธ์กฐํ๋ ์์ผ๋ก ์๋ํ๋ค.
String str = "hello";
str = str + " world";
System.out.println(str); // hello world
์ด์ธ์๋ ๋ฌธ์์ด์ ๋ค๋ฃจ๋๋ฐ ์์ด ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ trim ์ด๋ toUpperCase ๋ฉ์๋ ์ฌ์ฉ ํํ๋ฅผ ๋ณด๋ฉด, ๋ฌธ์์ด์ด ๋ณ๊ฒฝ๋๋ ๊ฒ ์ฒ๋ผ ์๊ฐ ๋ ์๋ ์์ง๋ง ํด๋น ๋ฉ์๋ ์ํ ์ ๋ ๋ค๋ฅธ String ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฆฌํดํ ๋ฟ์ด๋ค.
String sql = "abc"; // "abc"
sql.toUpperCase(); // "ABC"
System.out.println(sql); // "abc" - toUpperCase๋ฅผ ํด๋ ์์ฒด ๋ฌธ์์ด์ ๋ณ๊ฒฝ๋์ง ์๋๋ค (๋ถ๋ณ)
[ ์๋ฐ ์ธ์ด์์ String์ ๋ถ๋ณ์ผ๋ก ์ค์ ํ ์ด์ ]
String ๊ฐ์ฒด๋ฅผ ๋ถ๋ณํ๊ฒ ์ค๊ณํ ์ด์ ๋ ์บ์ฑ, ๋ณด์, ๋๊ธฐํ, ์ฑ๋ฅ์ธก๋ฉด ์ด์ ์ ์ป๊ธฐ ์ํด์์ด๋ค.
1. ์บ์ฑ : String์ ๋ถ๋ณํ๊ฒ ํจ์ผ๋ก์จ String pool์ ๊ฐ ๋ฆฌํฐ๋ด ๋ฌธ์์ด์ ํ๋๋ง ์ ์ฅํ๋ฉฐ ๋ค์ ์ฌ์ฉํ๊ฑฐ๋ ์บ์ฑ์ ์ด์ฉ๊ฐ๋ฅํ๋ฉฐ ์ด๋ก ์ธํด ํ ๊ณต๊ฐ์ ์ ์ฝํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค.
2. ๋ณด์ : ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ์ ์ด๋ฆ, ์ํธ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ์์ ํ๊ธฐ ์ํด ๋ฌธ์์ด๋ก ์ ๋ฌ๋๋๋ฐ, ๋ง์ผ ๋ฒ์ง์์ ๋ฌธ์์ด ๊ฐ์ด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค๋ฉด ํด์ปค๊ฐ ์ฐธ์กฐ ๊ฐ์ ๋ณ๊ฒฝํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค.
3. ๋๊ธฐํ : ๋ถ๋ณํจ์ผ๋ก์จ ๋์์ ์คํ๋๋ ์ฌ๋ฌ ์ค๋ ๋์์ ์์ ์ ์ด๊ฒ ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ค.
StringBuffer / StringBuilder ๋ ๊ฐ๋ณ
StringBuffer๋ StringBuilder์ ๊ฒฝ์ฐ ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ๋ค๋ ์ ์์ String ๊ฐ์ฒด์ ๊ฐ์ง๋ง, ๊ฐ์ฒด์ ๊ณต๊ฐ์ด ๋ถ์กฑํด์ง๋ ๊ฒฝ์ฐ ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ ์ฐํ๊ฒ ๋๋ ค์ฃผ์ด ๊ฐ๋ณ(mutable)์ ์ด๋ผ๋ ์ฐจ์ด์ ์ด ์๋ค.
๋ ํด๋์ค๋ ๋ด๋ถ Buffer(๋ฐ์ดํฐ๋ฅผ ์์๋ก ์ ์ฅํ๋ ๋ฉ๋ชจ๋ฆฌ)์ ๋ฌธ์์ด์ ์ ์ฅํด๋๊ณ ๊ทธ ์์์ ์ถ๊ฐ, ์์ , ์ญ์ ์์ ์ ํ ์ ์๋๋ก ์ค๊ณ๋์ด ์๋ค.
String ๊ฐ์ฒด๋ ํ๋ฒ ์์ฑ๋๋ฉด ๋ถ๋ณ์ ์ธ ํน์ง ๋๋ฌธ์ ๊ฐ์ ์ ๋ฐ์ดํธํ๋ฉด, ๋งค ์ฐ์ฐ ์๋ง๋ค ์๋ก์ด ๋ฌธ์์ด์ ๊ฐ์ง String ์ธ์คํด์ค๊ฐ ์์ฑ๋์ด ๋ฉ๋ชจ๋ฆฌ๊ณต๊ฐ์ ์ฐจ์งํ๊ฒ ๋์ง๋ง,
StringBuffer / StringBuilder ๋ ๊ฐ๋ณ์ฑ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ .append() .delete() ๋ฑ์ API๋ฅผ ์ด์ฉํ์ฌ ๋์ผ ๊ฐ์ฒด๋ด์์ ๋ฌธ์์ด ํฌ๊ธฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
๋ฐ๋ผ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋กญ๊ฒ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ String ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ธฐ ๋๋ฌธ์, ๋ฌธ์์ด์ ์ถ๊ฐ, ์์ , ์ญ์ ๊ฐ ๋น๋ฒํ๊ฒ ๋ฐ์ํ ๊ฒฝ์ฐ๋ผ๋ฉด String ํด๋์ค๊ฐ ์๋ StringBuffer / StringBuilder๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ด์์ ์ด๋ผ ๋งํ ์ ์๋ค.
StringBuilder ๋ StringBuffer ํด๋์ค์ ์ฌ์ฉ ๋ฌธ๋ฒ์ ๋์ด ๋๊ฐ๋ค.
๋ค๋ง ๋ด๋ถ์ ์ผ๋ก ๋์ ์ฐจ์ด์ ์กด์ฌํ๋๋ฐ ์ด์ ๋ํด์ ๋ฐ๋ก ๋ค์์ ๋ค๋ฃฌ๋ค. ์ง๊ธ์ ๋์ด ๋์ผ์๋ก ๋ด๋ ๋๋ค.
StringBuffer์ ๋ด๋ถ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ์์(final) ํค์๋๊ฐ ์๋๊ฒ์ ๋ณผ ์ ์๋ค.
public final class StringBuffer implements java.io.Serializable {
private byte[] value;
}
StringBuffer sb = new StringBuffer(); // new StringBuffer() ์ธ์์ ์๋ฌด๊ฒ๋ ๋ฃ์ด์ฃผ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ 16์ผ๋ก ๋ฐฐ์ด ๊ธธ์ด๋ฅผ ์ก์
// sb.capacity() - StringBuffer ๋ณ์์ ๋ฐฐ์ด ์ฉ๋์ ํฌ๊ธฐ ๋ฐํ
System.out.println(sb.capacity()); // 16
sb.append("1111111111111111111111111111111111111111"); // 40๊ธธ์ด์ ๋ฌธ์์ด์ append
System.out.println(sb.capacity()); // 40 (์ถ๊ฐ๋ ๋ฌธ์์ด ๊ธธ์ด๋งํผ ๋์ด๋จ)
์๋ ์ฝ๋๋ ๋ณ* ๋ฌธ์๋ฅผ ๋ฃจํ๋ฌธ์ ์ํํ ๋๋ง๋ค ์ถ๊ฐํด ๊ธธ๋ค๋ ๋ณ ๋ฌธ์์ด์ ๋ง๋๋ ์์ ๋ก, ๊ฐ๊ฐ String ๊ฐ์ฒด์ StringBuffer ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์์ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ค๋ค.
String star = "*";
for ( int i = 1; i < 10; i++ ) {
star += "*";
}
StringBuffer sb= new StringBuffer("*");
sb.append("*********");
String ๊ฐ์ฒด์ผ ๊ฒฝ์ฐ ๋งค๋ฒ ๋ณ ๋ฌธ์์ด์ด ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ๊ณ์ํด์ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ญ์ด ์ถ๊ฐ๋๊ฒ ๋๊ณ , ์ผํ์ฉ์ผ๋ก ์ฌ์ฉ๋ ์ด ๋ฉ๋ชจ๋ฆฌ๋ค์ ํ์ Garbage Collector(GC)์ ์ ๊ฑฐ ๋์์ด ๋์ด ๋น๋ฒํ๊ฒ Minor GC๋ฅผ ์ผ์ผ์ผ Full GC(Major Gc)๋ฅผ ์ผ์ผํฌ์ ์๋ ์์ธ์ด ๋๋ค. (์๋ฐ ๋ฉ๋ชจ๋ฆฌ GC ๊ด๋ฆฌ ์ฐธ๊ณ ๊ธ)
๋ฐ๋ฉด StringBuffer๋ ์ ์ฌ์ง ์ฒ๋ผ ์์ฒด ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ญ์์ ๋์ด๊ณ ์ค์ด๊ณ ๋ฅผ ํ ์ ์๊ธฐ ๋๋ฌธ์ ํจ์ฌ๋ ํจ์จ์ ์ผ๋ก ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ์ ์๋ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ฌธ์์ด ์๋ฃํ์ ๊ฐ ๋น๊ต
String ๊ฐ ๋๋ฑ ๋น๊ต
String ๊ฐ์ฒด๋ ๊ฐ๋จํ๊ฒ equals() ๋ฉ์๋๋ฅผ ํตํด ๋ฌธ์์ด ๋ฐ์ดํฐ ๋๋ฑ ๋น๊ต๊ฐ ๊ฐ๋ฅํ๋ค.
String str1 = "Hello"; // ๋ฌธ์์ด ๋ฆฌํฐ๋ด์ ์ด์ฉํ ๋ฐฉ์
String str3 = new String("Hello"); // new ์ฐ์ฐ์๋ฅผ ์ด์ฉํ ๋ฐฉ์
// ๋ฆฌํฐ๋ด๊ณผ ๊ฐ์ฒด ๋ฌธ์์ด ๋น๊ต
System.out.println(str1 == str3); // false
System.out.println(str3.equals(str1)); // true
StringBuffer / StringBuilder ๊ฐ ๋๋ฑ ๋น๊ต
ํ์ง๋ง StringBuffer/StringBuilder ํด๋์ค๋ String ๊ฐ์ฒด์ ๋ฌ๋ฆฌ equals() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ง ์์ '==' ๋ก ๋น๊ตํ ๊ฒ๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ฒ ๋ ๋ฒ๋ฆฐ๋ค.
StringBuffer sb = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("hello");
System.out.println(sb == sb2); // false
System.out.println(sb2.equals(sb)); // false
๋ฐ๋ผ์ toString() ์ผ๋ก StringBuffer/StringBuilder ๊ฐ์ฒด๋ฅผ String ๊ฐ์ฒด๋ก ๋ณํํ๊ณ ๋ ๋ค์ equals ๋ก ๋น๊ต๋ฅผ ํด์ผ ํ๋ค. (์ฝ๊ฐ ๋ฒ๊ฑฐ๋กญ๋ค)
// StringBuffer๊ฐ์ฒด๋ฅผ toString()์ ํตํด String๊ฐ์ฒดํ๋ฅผ ํ๊ณ equals ๋น๊ต
String sb_tmp = sb.toString();
String sb2_tmp = sb2.toString();
System.out.println(sb_tmp.equals(sb2_tmp)); // true
๋ฌธ์์ด ์๋ฃํ์ ์ฑ๋ฅ ๋น๊ต
๋ฌธ์์ด ํฉ์น๊ธฐ ์ฑ๋ฅ
์๋ฐ๋ฅผ ๊ฐ๋ฐ ํ๋ค๋ณด๋ฉด ๋ฌธ์์ด์ ๋ค๋ฃจ๋๋ฐ ์์ด, ๋ณ๋ค๋ฅธ ๊ณ ๋ฏผ์์ด "Hello" + " World" ์ ๊ฐ์ด + ๊ธฐํธ๋ฅผ ํตํด ๋ฌธ์์ด์ ์ด์ด ๋ถ์ด๊ณค ํ๋ค. ํ์ง๋ง ์ฐธ๋ Java ๊ฐ๋ฐ์๋ผ๋ฉด ๊ณ ๋ฏผ์ ๋ ํด๋ณด๊ณ ๋ฌธ์์ด ๊ด๋ จ Class๋ฅผ ์ ํํด์ผํ๋ค.
์์์ ์์๋ดค๋ฏ์ด, String ๋ฐ์ดํฐ๋ฅผ + ์ฐ์ฐํ๋ฉด ๋ถํ์ํ ๊ฐ์ฒด๋ค์ด ํ ๋ฉ๋ชจ๋ฆฌ์ ์ถ๊ฐ๋์ด ์์ข๊ธฐ ๋๋ฌธ์ String์ ์ง์ + ์ฐ์ฐ์ ํตํ ๋ฌธ์์ด ํฉ์น๊ธฐ๋ฅผ ์ง์ํ๊ณ StringBuffer๋ StringBuilder์ append() ๋ฉ์๋๋ฅผ ํตํด ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข๋ค๊ณ ํ๋ค.
ํ์ง๋ง ์ด๋ ๋ฐ์ ๋ง๊ณ ๋ฐ์ ํ๋ฆฐ ๋ง์ด๋ค.
์ฌ์ค ์๋ฐ๋ ๋ฌธ์์ด์ + ์ฐ์ฐ์ ์ฌ์ฉํ๋ฉด, ์ปดํ์ผ ์ ๋ด๋ถ์ ์ผ๋ก StringBuilder ํด๋์ค๋ฅผ ๋ง๋ ํ ๋ค์ ๋ฌธ์์ด๋ก ๋๋ ค์ค๋ค๊ณ ํ๋ค.
์ฆ, "hello" + "world" ๋ฌธ์์ด ์ฐ์ฐ์ด ์๋ค๋ฉด ์ด๋ new StringBuilder("hello").append("world").toString() ๊ณผ ๊ฐ๋ค๋ ๋ง์ด๋ค.
String a = "hello" + "world";
/* ๋ ์๋์ ๊ฐ๋ค. */
String a = new StringBuilder("hello").append("world").toString();
// StringBuilder๋ฅผ ํตํด "hello" ๋ฌธ์์ด์ ์์ฑํ๊ณ "world"๋ฅผ ์ถ๊ฐํ๊ณ toString()์ ํตํด String ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ๋ฐํ
์ด์ฒ๋ผ ๊ฒ์ผ๋ก๋ ๋ณด๊ธฐ์๋ ๋ฌธ์์ด ๋ฆฌํฐ๋ด๋ก + ์ฐ์ฐํ๊ฑฐ๋, StringBuilder ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ด์ฐจํผ ์๋ ๋ณํํด์ค์ ์ฐจ์ด๊ฐ ์์ด ๋ณด์ผ์ง๋ ๋ชจ๋ฅธ๋ค.
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ๋ฌธ์์ด์ ํฉ์น๋ ์ผ์ด ๋ง์ ๊ฒฝ์ฐ ๋จ์ํ + ์ฐ์ฐ์ ์ฐ๋ฉด ์ฑ๋ฅ๊ณผ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ๋จ์ด์ง๊ฒ ๋๋ค.
String a = "";
for(int i = 0; i < 10000; i++) {
a = a + i;
}
/* ์์ ๋ฌธ์์ด + ์ฐ์ฐ ์์ ๊ฒฐ๊ตญ ์๋์ ๊ฐ๋ค. */
/* ์ฆ, ๋งค๋ฒ new StringBuilder() ๊ฐ์ฒด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ๋ค์ ๋ณ์์ ๋์
ํ๋ ๋ฉ์ฒญํ ์ง๊ฑฐ๋ฆฌ๋ฅผ ํ๊ณ ์๋ ๊ฒ์ด๋ค. */
String a = "";
for(int i = 0; i < 10000; i++) {
a = new StringBuilder(b).append(i).toString();
}
์์ ์์ ์ฒ๋ผ ๋งค๋ฒ new StringBuilder() ๊ฐ์ฒด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ๋ค์ ๋ณ์์ ๋์
ํ๋ ๋ฉ์ฒญํ ์ง์ ๋ฐ๋ณตํ๊ณ ์์ผ๋ ํ๋์ ๋ด๋ ๋ฌธ์์ด ๊ฐ์ ๋ณ๊ฒฝํ ์ผ์ด ์ฆ์ ๊ฒฝ์ฐ + ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ง ๋ชปํ ๊ฒ์ ์ ์ ์๋ค.
๋ฐ๋ผ์ ๋ง์ผ ๋ฌธ์์ด ์ฐ์ฐ์ด ๋ง์ ๊ฒฝ์ฐ ์์ ์ฒ์๋ถํฐ StringBuilder() ๊ฐ์ฒด๋ก ๋ฌธ์์ด์ ์์ฑํด์ ๋ค๋ฃจ๋๊ฒ ํจ์ฌ ๋ซ๋ค.
StringBuilder a = new StringBuilder();
for(int i = 0; i < 10000; i++) {
a.append(i);
}
final String b = a.toString();
String.concat ๊ณผ์ ๋น๊ต
์๋ฐ ํ๋ก๊ทธ๋๋ฐ์์ ๋ฌธ์์ด์ ํฉ์น๋๋ฐ ์์ด ์ด 4๊ฐ์ง ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค.
+ ์ฐ์ฐ์ ๋๋ String.concat ๋ฉ์๋ ์ด์ฉ ๋๋ StringBuffer ๋๋ StringBuilder ๊ฐ์ฒด๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
String str = "hello ";
String a = str + "world"; // ์์ + ์ฐ์ฐ์ ์๋์ผ๋ก StringBuilder๋ก ๋ณํ๋๋ค๊ณ ๋งํ๋ค.
String b = str.concat("world");
String c = new StringBuffer("hello").append("world").toString();
String d = new StringBuilder("hello").append("world").toString();
์ด์ฒ๋ผ String ๊ฐ์ฒด ์์ฒด์๋ String.concat ๋ฉ์๋๋ก ์์ฒด ๋ฉ๋ชจ๋ฆฌ ์์ญ์์ ๋ฌธ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค.
๊ทธ๋ผ ์ด์ค์ ์ด๋ ๊ฒ์ด ์ฑ๋ฅ์ด ์ข์๊น? ๋น์ฐํ ์น์๋ StringBuffer ์ StringBuilder ๊ฐ์ฒด์ด๋ค.
String.concat ๊ฐ์ ๊ฒฝ์ฐ, ์ด ๋ฉ์๋๋ ํธ์ถํ ๋๋ง๋ค ์๋ณธ ๋ฌธ์์ด์ ๋งค๋ฒ ๋ฐฐ์ด์ ์ฌ๊ตฌ์ฑ ํ๋ ๊ณผ์ ์ ๊ฑฐ์น๊ธฐ ๋๋ฌธ์ ๋น์ฐํ ๋๋ฆด ์๋ฐ์ ์๋ค. ๋ฐ๋ฉด StringBuilder๋ StringBuffer๋ ์ฒ์๋ถํฐ ๋ฐฐ์ด ํฌ๊ธฐ๋ฅผ ์ผ์ ํ๊ฒ ์ก๊ณ ์์ํ๊ธฐ ๋๋ฌธ์ ํฉ์น๋ ๊ณผ์ ์ด String.concat ๋ณด๋ค ์๋ฑํ ๋น ๋ฅด๋ค.
์ฑ๋ฅ์์์ ๋ฌธ์์ด ์๋ฃํ ์ ํ ๊ฒฐ๋ก
๊ทธ๋ ๋ค๋ฉด ๋ฌด์กฐ๊ฑด StringBuffer / StringBuilder๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์๋ค๊ณ ๋งน์ ํ ์ ์๊ฒ ์ง๋ง, ๊ทธ๊ฑด ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค.
StringBuffer๋ StringBuilder์ ์์ฑํ ๊ฒฝ์ฐ buffer์ ํฌ๊ธฐ๋ฅผ ์ด๊ธฐ์ ์ค์ ํด์ค์ผํ๋๋ฐ ์ด๋ฌํ ๋์์ผ๋ก ์ธํด ๋ฌด๊ฑฐ์ด ํธ์ ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ StringBuffer๋ StringBuilder์์ ๋ฌธ์์ด ์์ ์ ํ ๊ฒฝ์ฐ์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ๋๋ฆฌ๊ณ ์ค์ด๊ณ ๋ช ์นญ์ ๋ณ๊ฒฝํด์ผํ๋ ๋ด๋ถ์ ์ธ ์ฐ์ฐ์ด ํ์ํ๋ฏ๋ก ๋ง์ ์์ ๋ฌธ์์ด ์์ ์ด ์๋๋ผ๋ฉด String ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋๊ฒ์ด ์คํ๋ ค ๋์ ์ ์๋ค.
String ํด๋์ค๋ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด ์์ผ๋ฏ๋ก ๋จ์ํ๊ฒ ์ฝ๋ ์กฐํ ์ฐ์ฐ์์๋ StringBuffer๋ StringBuilder ํด๋์ค๋ณด๋ค ๋น ๋ฅด๊ฒ ์ฝ์ ์ ์๋ค.
๋ฐ๋ผ์ ์ ๋ฆฌํ์๋ฉด, ๋ฌธ์์ด ์ถ๊ฐ๋ ๋ณ๊ฒฝ๋ฑ์ ์์ ์ด ๋ง์ ๊ฒฝ์ฐ์๋ StringBuffer๋ฅผ, ๋ฌธ์์ด ๋ณ๊ฒฝ ์์ ์ด ๊ฑฐ์ ์๋ ๊ฒฝ์ฐ์๋ ๊ทธ๋ฅ String์ ์ฌ์ฉํ๋ ๊ฒ๋ง ๊ธฐ์ตํ๋ฉด ๋๋ค.
StringBuffer vs StringBuilder ์ฐจ์ด์
StringBuffer์ StringBuilder ํด๋์ค๋ ๋ ๋ค ํฌ๊ธฐ๊ฐ ์ ์ฐํ๊ฒ ๋ณํ๋ ๊ฐ๋ณ์ ์ธ ํน์ฑ์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ ๊ณตํ๋ ๋ฉ์๋๋ ๋๊ฐ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ๋์ผํ๋ค.
๊ทธ๋ผ ์ด ๋์ ์ฐจ์ด์ ์ ๋ฌด์์ผ๊น? ์ด๋ ต๊ฒ ์๊ฐํ ํ์์์ด, ์ฌ์ค ๋์ ์ฐจ์ด๋ ๋ฑ ํ๊ฐ์ง์ด๋ค.
๋ฐ๋ก ๋ฉํฐ ์ฐ๋ ๋(Thread)์์ ์์ (safe)ํ๋ ์๋๋ ์ด ์ฐจ์ด ๋ฟ์ด๋ค.
์ฐ๋ ๋์ ์์ ์ฑ
- StringBuffer ํด๋์ค๋ ์ฐ๋ ๋์์ ์์ ํ๋ค. (thread safe)
- StringBuilder ํด๋์ค๋ ์ฐ๋ ๋์์ ์์ ํ์ง ์๋ค.(thread unsafe)
๋ ํด๋์ค๋ ๋ฌธ๋ฒ์ด๋ ๋ฐฐ์ด๊ตฌ์ฑ๋ ๋ชจ๋ ๊ฐ์ง๋ง, ๋๊ธฐํ(Synchronization)์์์ ์ง์์ ์ ๋ฌด๊ฐ ๋ค๋ฅด๋ค.
StringBuilder๋ ๋๊ธฐํ๋ฅผ ์ง์ํ์ง ์๋ ๋ฐ๋ฉด, StringBuffer๋ ๋๊ธฐํ๋ฅผ ์ง์ํ์ฌ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ๊ฒ ๋์ํ ์ ์๋ค.
๊ทธ ์ด์ ๋ StringBuffer๋ ๋ฉ์๋์์ synchronized ํค์๋๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
java์์ synchronized ํค์๋๋ ์ฌ๋ฌ๊ฐ์ ์ค๋ ๋๊ฐ ํ ๊ฐ์ ์์์ ์ ๊ทผํ ๋ ค๊ณ ํ ๋, ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ์ค๋ ๋๋ฅผ ์ ์ธํ๊ณ ๋๋จธ์ง ์ค๋ ๋๋ค์ด ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๋๋ก ๋ง๋ ์ญํ ์ ์ํํ๋ค.
๊ธ๋ก๋ง ๋ณด๋ฉด ์ด๊ฒ ์ ํํ ์ด๋ค ํ์์ธ์ง ์๋ฟ์ง ์๋๋ค. ์ง์ StringBuilder์ StringBuffer๋ฅผ ์ฝ๋๋ก ํ ์คํธ ํด๋ณด์.
์๋์ ์์ ๋ StringBuilder์ StringBuffer ๊ฐ์ฒด๋ฅผ ์ ์ธํ๊ณ , ๋๊ฐ์ ๋ฉํฐ ์ฐ๋ ๋๋ฅผ ๋๋ ค StringBuilder์ StringBuffer ๊ฐ์ฒด์ ๊ฐ๊ฐ 1 ์์๋ฅผ 1๋ง๋ฒ ์ถ๊ฐํ๋(append) ๋ก์ง์ ์ํํ ์ฝ๋์ด๋ค.
๋๊ฐ์ ์ฐ๋ ๋๊ฐ ์๊ณ ํ๊ฐ์ ์ฐ๋ ๋์์ ๋ฐฐ์ด์์๋ฅผ 1๋ง๋ฒ ์ถ๊ฐํ๋ ๋ฌธ์์ด ๋ฐฐ์ด์ ๊ธธ์ด๋ 20000์ด ๋๋ค๊ณ ์ ์ถํ ์ ์๋ค.
import java.util.*;
public class Main extends Thread{
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer();
StringBuilder stringBuilder = new StringBuilder();
new Thread(() -> {
for(int i=0; i<10000; i++) {
stringBuffer.append(1);
stringBuilder.append(1);
}
}).start();
new Thread(() -> {
for(int i=0; i<10000; i++) {
stringBuffer.append(1);
stringBuilder.append(1);
}
}).start();
new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println("StringBuffer.length: "+ stringBuffer.length()); // thread safe ํจ
System.out.println("StringBuilder.length: "+ stringBuilder.length()); // thread unsafe ํจ
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
StringBuffer.length: 20000
StringBuilder.length: 19628
ํ์ง๋ง ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋ค๋ฅธ ๊ฐ์ด ๋์จ ๊ฒ์ ๋ณผ ์ ์๋ค.
StringBuilder์ ๊ฐ์ด ๋ ์์ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ์ด๋ ์ฐ๋ ๋๋ค์ด ๋์์ StringBuilder ํด๋์ค์ ์ ๊ทผํ์ฌ ๋์์ append() ๋ฅผ ์ํํ๋ค ๋ช๋ฒ ์นํ์ ์ ๋๋ก ์ํ์ด ์๋์ด ์ผ์ด๋ ๊ฒฐ๊ณผ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
StringBuilder๋ Thread safe ํ์ง ์์์ ๊ฐ๊ธฐ ์ฐ๋ ๋๊ฐ ๊ฐ์ฒด์ ์ ๊ทผํด์ ๋ณ๊ฒฝ์ ํ๋ฉด ๊ธฐ๋ค๋ ค์ฃผ์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ํ์์ด ๋ฐ์ํ ๊ฒ์ด๋ค.
์ด์ ๋ฌ๋ฆฌ StringBuffer๋ ๋ฉํฐ ์ฐ๋ ๋(multi thread)ํ๊ฒฝ์์, ํ ์ฐ๋ ๋๊ฐ append() ๋ฅผ ์ํํ๊ณ ์์๊ฒฝ์ฐ ๋ค๋ฅธ ์ฐ๋ ๋๊ฐ append() ๋ฅผ ์ํ์ ๋์์ ํ์ง๋ชปํ๋๋ก ์ ์ ๋๊ธฐ๋ฅผ ์์ผ์ฃผ๊ณ ์์ฐจ์ ์ผ๋ก ์คํํ๊ฒ ํ๋ค. ์ด์ฒ๋ผ ๋์์ ์ ๊ทผํด ๋ค๋ฅธ ๊ฐ์ ๋ณ๊ฒฝํ์ง ๋ชปํ๋๋ก ํ๋ฏ๋ก Thread Safe๋ก์ ์ ์์ ์ผ๋ก 2๋ง๊ฐ์ ๋ฐฐ์ด์์๊ฐ ์ถ๊ฐ๋ ๊ฒ์ด๋ค.
๊ทธ๋์ web์ด๋ ์์ผํ๊ฒฝ๊ณผ ๊ฐ์ด ๋น๋๊ธฐ๋ก ๋์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๋๋ StringBuffer๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํ๋ค๋ ๊ฒ์ ์์๊ฐ ์๋ค.
์์ ์ฑ๋ฅ ๋น๊ต
๊ทธ๋ผ ์์ํ๊ฒ ์ด ๋ ํด๋์ค์ ์ฑ๋ฅ์ ๋๊ฐ ์ฐ์ํ ๊น?
๋ค์์ String ๊ฐ์ฒด ๊ทธ๋ฆฌ๊ณ StringBuffer์ StringBuilder ๊ฐ์ฒด๋ฅผ ์ ์ธํ๊ณ 5๋ง๋ฒ์ ๋ฃจํํด ๋ณ๋ฌธ์ * ๋ฅผ ์ถ๊ฐํ๋ ๋ก์ง์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ ๋ฌธ์์ด ์ฐ์ฐ์ ์คํํ๋ ์๊ฐ์ duration1, duration2, duration3 ๋ณ์์ ๊ณ์ฐํด ์ ์ฅํ๋ค.
final int lengths = 50000;
// ------------- (1) String์ +์ฐ์ฐ์ ์ด์ฉํด์ 50,000๊ฐ์ *๋ฅผ ์ด์ด ๋ถ์ธ๋ค.
long startTime1 = System.currentTimeMillis(); // ์์์๊ฐ์ ๊ธฐ๋ก (millisecond๋จ์)
String str="";
for(int i=0;i<lengths;i++){
str=str+"*";
}
long endTime1 = System.currentTimeMillis(); // ์ข
๋ฃ์๊ฐ์ ๊ธฐ๋ก(millisecond๋จ์)
// ------------- (2) StringBuffer๋ฅผ ์ด์ฉํด์ 50,000๊ฐ์ *๋ฅผ ์ด์ด๋ถ์ธ๋ค.
long startTime2 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0;i<lengths;i++){
sb.append("*");
}
long endTime2 = System.currentTimeMillis();
// ------------- (3) StringBuilder๋ฅผ ์ด์ฉํด์ 50,000๊ฐ์ *๋ฅผ ์ด์ด๋ถ์ธ๋ค.
long startTime3 = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder();
for(int i=0;i<lengths;i++){
sb2.append("*");
}
long endTime3 = System.currentTimeMillis();
// ------------- ๋ฐฉ๋ฒ(1), ๋ฐฉ๋ฒ(2), ๋ฐฉ๋ฒ(3)๊ฐ ๊ฑธ๋ฆฐ ์๊ฐ์ ๋น๊ต
long duration1 = endTime1 - startTime1;
long duration2 = endTime2 - startTime2;
long duration3 = endTime3 - startTime3;
System.out.println("String์ +์ฐ์ฐ์ ์ด์ฉํ ๊ฒฝ์ฐ : "+ duration1); // 559
System.out.println("StringBuffer์ append()์ ์ด์ฉํ ๊ฒฝ์ฐ : "+ duration2); // 10
System.out.println("StringBuilder์ append()์ ์ด์ฉํ ๊ฒฝ์ฐ : "+ duration3); // 3
String์ +์ฐ์ฐ์ ์ด์ฉํ ๊ฒฝ์ฐ : 559
StringBuffer์ append()์ ์ด์ฉํ ๊ฒฝ์ฐ : 10
StringBuilder์ append()์ ์ด์ฉํ ๊ฒฝ์ฐ : 3
๋ฌธ์์ด ์ฐ์ฐ ์ํ ์๊ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, ๊ธฐ๋ณธ ์ฑ๋ฅ์ StringBuilder ํด๋์ค๊ฐ ์ฐ์ํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
์์์ ์ดํด๋ณด์๋ + ์ฐ์ฐ ์, ์ปดํ์ผ ์ ์ StringBuilder ๋ก ๋ณํํด์ฃผ๋ ์ด์ ๊ฐ ๋ฐ๋ก ์ด๊ฒ์ด๋ค.
์ด๋ ์กฐ๊ธ๋ง ์๊ฐํด๋ณด๋ฉด ๋น์ฐํ ๊ฒฐ๊ณผ์ด๋ค.
StringBuffer์ StringBuilder ์ ์ฐจ์ด๋ ์ฐ๋ ๋ ์์ ์ฑ์ ์๋ค๊ณ ํ์ตํ๋๋ฐ, ์๋ฌด๋๋ ์ฐ๋ ๋ ์์ ์ฑ์ ๋ฒ๋ฆฐ StringBuilder๊ฐ ์ข๋ ๋ ๋ฐ์ง๊ณ ์ฐ์ฐ์ ํ๋ ๋น์ฐํ ์ข ๋ ๋น ๋ฅผ ์ ๋ฐ์ ์๋ค.
์ ๊ทธ๋ํ๋ฅผ ๋ณด๋ฉด 10๋ง๋ฒ ์ด์์ ์ฐ์ฐ์ String ๊ฐ์ฒด๋ ์ํ์๊ฐ์ด ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋์ง๋ง, StringBuilder์ StringBuffer๋ 1000๋ง๋ฒ๊น์ง ๋ฒํฐ๋ฉฐ, ๊ทธ ์ด์์ StringBuilder๊ฐ ์ฐ์ํ๋ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๊ทธ๋์ ๋ง์ฝ ์ฑ๊ธ ์ฐ๋ ๋ ํ๊ฒฝ์์๋ ๋น๋๊ธฐ๋ฅผ ์ฌ์ฉํ ์ผ์ด ์์ผ๋ฉด, StringBuilder๋ฅผ ์ฐ๋ ๊ฒ์ด ์ด์์ ์ด๋ผ ํ ์ ์๋ค.
ํ์ง๋ง ํ์ ์์๋ ์๋ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋๋ถ๋ถ ๋ฉํฐ ์ค๋ ๋ ์ด์์ ํ๊ฒฝ์์ ๋์๊ฐ๊ธฐ ๋๋ฌธ์ ์ ๋งํ๋ฉด ์์ ์ ์ธ StringBuffer๋ก ํต์ผํ์ฌ ์ฝ๋ฉํ๋๊ฒ์ด ์ข๋ค. (์์งํ StringBuffer ์ StringBuilder ์๋ ์ฐจ์ด๋ ๊ฑฐ์ ๋ฏธ๋ฏธํ๋ค)
๋ฌธ์์ด ์๋ฃํ ๋น๊ต ์ด์ ๋ฆฌ
String | StringBuffer | StringBuilder | |
๊ฐ๋ณ ์ฌ๋ถ | ๋ถ๋ณ | ๊ฐ๋ณ | ๊ฐ๋ณ |
์ค๋ ๋ ์ธ์ดํ | O | O | X |
์ฐ์ฐ ์๋ | ๋๋ฆผ | ๋น ๋ฆ | ์์ฃผ ๋น ๋ฆ |
์ฌ์ฉ ์์ | ๋ฌธ์์ด ์ถ๊ฐ ์ฐ์ฐ์ด ์ ๊ณ , ์ค๋ ๋ ์ธ์ดํ ํ๊ฒฝ์์ | ๋ฌธ์์ด ์ถ๊ฐ ์ฐ์ฐ์ด ๋ง๊ณ , ์ค๋ ๋ ์ธ์ดํ ํ๊ฒฝ์์ | ๋ฌธ์์ด ์ถ๊ฐ ์ฐ์ฐ์ด ๋ง๊ณ , ๋น ๋ฅธ ์ฐ์ฐ์ด ํ์ํ ๊ฒฝ์ฐ ๋จ์ผ ์ค๋ ๋ ํ๊ฒฝ์ผ๊ฒฝ์ฐ |
- String ์ ์ฌ์ฉํด์ผ ํ ๋ :
- String์ ๋ถ๋ณ์ฑ
- ๋ฌธ์์ด ์ฐ์ฐ์ด ์ ๊ณ ๋ณํ์ง ์๋ ๋ฌธ์์ด์ ์์ฃผ ์ฌ์ฉํ ๊ฒฝ์ฐ
- ๋ฉํฐ์ฐ๋ ๋ ํ๊ฒฝ์ผ ๊ฒฝ์ฐ
- StringBuilder ๋ฅผ ์ฌ์ฉ ํด์ผ ํ ๋ :
- StringBuilder๋ ๊ฐ๋ณ์ฑ
- ๋ฌธ์์ด์ ์ถ๊ฐ, ์์ , ์ญ์ ๋ฑ์ด ๋น๋ฒํ ๋ฐ์ํ๋ ๊ฒฝ์ฐ
- ๋๊ธฐํ๋ฅผ ์ง์ํ์ง ์์, ๋จ์ผ ์ฐ๋ ๋์ด๊ฑฐ๋ ๋๊ธฐํ๋ฅผ ๊ณ ๋ คํ์ง ์์๋ ๋๋ ๊ฒฝ์ฐ
- ์๋๋ฉด์์ StringBuffer ๋ณด๋ค ์ฑ๋ฅ์ด ์ข๋ค.
- StringBuffer ๋ฅผ ์ฌ์ฉํด์ผ ํ ๋ :
- StringBuffer๋ ๊ฐ๋ณ์ฑ
- ๋ฌธ์์ด์ ์ถ๊ฐ, ์์ , ์ญ์ ๋ฑ์ด ๋น๋ฒํ ๋ฐ์ํ๋ ๊ฒฝ์ฐ
- ๋๊ธฐํ๋ฅผ ์ง์ํ์ฌ, ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ๊ฒ ๋์
# ์ฐธ๊ณ ์๋ฃ
https://stackoverflow.com/questions/32714194/where-is-implemented-for-strings-in-the-java-source-code
https://dejavuhyo.github.io/posts/string-stringbuffer-stringbuilder/
https://venishjoe.net/post/java-string-concatenation-and-performance/
https://madplay.github.io/post/difference-between-string-stringbuilder-and-stringbuffer-in-java
https://wikidocs.net/276
https://velog.io/@minnseong/String