Java에서 String과 StringBuffer의 차이점은 무엇입니까?
Java에서 String과 StringBuffer의 차이점은 무엇입니까?
String의 최대 크기가 있습니까?
String
변경할 수없는 (읽기 전용 및 불변) 문자열을 조작하는 데 사용됩니다.
StringBuffer
수정할 수있는 문자를 나타내는 데 사용됩니다.
성능면에서 StringBuffer
연결을 수행 할 때 더 빠릅니다. 를 연결할 때는 변경 불가능 String
하므로 매번 새 객체 (내부적으로)를 생성하기 때문 String
입니다.
동기화되지 않는다는 점 StringBuilder
을 StringBuffer
제외하고 유사한 것을 사용할 수도 있습니다 . 이들 중 하나의 최대 크기는 Integer.MAX_VALUE
(2 31-1 = 2,147,483,647) 또는 최대 힙 크기를 2로 나눈 값입니다 ( Java 문자열에 사용할 수있는 문자 수 참조 ). 자세한 정보는 여기 .
A String
는 변경 불가능합니다. 즉, 생성 될 때 변경 될 수 없습니다.
A StringBuffer
(또는 동기화되지 않은 사촌 StringBuilder
)는 String
도중에 많은 작은 s 를 생성하는 성능 오버 헤드없이 문자열을 하나씩 구성해야 할 때 사용됩니다 .
둘 다의 최대 길이는 Integer.MAX_VALUE입니다. 내부적으로 배열로 저장되기 때문이며 Java 배열에는 int
길이 의사 필드 만 있습니다.
다중 연결에 대한 String
s와 StringBuffer
s 간의 성능 향상 은 상당히 중요합니다. 다음 테스트 코드를 실행하면 차이점을 알 수 있습니다. Java 6이 설치된 오래된 랩톱에서 다음과 같은 결과를 얻었습니다.
문자열을 사용한 연결 소요 시간 : 1781ms StringBuffer를 사용한 Concat 소요 시간 : 0ms
public class Concat
{
public static String concatWithString()
{
String t = "Cat";
for (int i=0; i<10000; i++)
{
t = t + "Dog";
}
return t;
}
public static String concatWithStringBuffer()
{
StringBuffer sb = new StringBuffer("Cat");
for (int i=0; i<10000; i++)
{
sb.append("Dog");
}
return sb.toString();
}
public static void main(String[] args)
{
long start = System.currentTimeMillis();
concatWithString();
System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
concatWithStringBuffer();
System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
}
}
String StringBuffer
Immutable Mutable
String s=new String("karthik"); StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy"); sb.append("reddy");
System.out.println(s); System.out.println(sb);
O/P:karthik O/P:karthikreddy
--->once we created a String object ---->once we created a StringBuffer object
we can't perform any changes in the existing we can perform any changes in the existing
object.If we are trying to perform any object.It is nothing but mutablity of
changes with those changes a new object of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object
Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety
String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object
String s="karthik";
--->In this case only one object will be created in scp and s is always pointing to that object only
문자열은 변경 불가능한 클래스입니다. 즉, 다음과 같이 문자열의 인스턴스를 인스턴스화하면 다음과 같습니다.
String str1 = "hello";
메모리의 개체는 변경할 수 없습니다. 대신 새 인스턴스를 만들고 이전 문자열을 복사 한 다음이 예에서와 같이 다른 것을 추가해야합니다.
String str1 = "hello";
str1 = str1 + " world!";
정말로 일어나고있는 것은 우리가 기존 str1 객체를 업데이트하지 않는다는 것입니다. 우리는 모두 함께 새 메모리를 재 할당하고 "hello"데이터를 복사하고 "world!"를 추가합니다. 끝까지 str1 참조가이 새 메모리를 가리 키도록 설정합니다. 따라서 실제로는 다음과 같이 보입니다.
String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;
따라서이 "복사 + 붙여 넣기 및 메모리에서 항목 이동"프로세스는 반복적으로 특히 재귀 적으로 수행되는 경우 매우 비쌀 수 있습니다.
일을 반복해야하는 상황에서 StringBuilder를 활용하십시오. 그것은 가변적이며 [성장하는 배열] (실제 데이터 구조 인 경우 100 %가 아니라 목록 일 수 있음)에 의해 돌아 오기 때문에 현재 문자열의 끝에 문자열을 추가 할 수 있습니다.
로부터 API :
스레드로부터 안전하고 변경 가능한 문자 시퀀스입니다. 문자열 버퍼는 문자열과 비슷하지만 수정할 수 있습니다. 어느 시점에서든 특정 문자 시퀀스가 포함되어 있지만 시퀀스의 길이와 내용은 특정 메서드 호출을 통해 변경할 수 있습니다.
StringBuffer는 여러 문자열에서 단일 문자열을 만드는 데 사용됩니다 (예 : 루프에서 문자열의 일부를 추가하려는 경우).
StringBuilder가 동기화되지 않아 더 빠르기 때문에 StringBuffer에 액세스하는 단일 스레드 만있는 경우 StringBuffer 대신 StringBuilder를 사용해야합니다.
AFAIK는 Java에서 언어로서의 문자열 크기에 대한 상한이 없지만 JVM에는 아마도 상한이 있습니다.
Reggie Hutcherso의 성능 비교 String vs StringBuffer에 대한 관심 답변을 찾았습니다 . 출처 : http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Java는 StringBuffer 및 String 클래스를 제공하며 String 클래스는 변경할 수없는 문자열을 조작하는 데 사용됩니다. 간단히 말해서 String 유형의 객체는 읽기 전용이며 변경할 수 없습니다. StringBuffer 클래스는 수정할 수있는 문자를 나타내는 데 사용됩니다.
이 두 클래스 간의 중요한 성능 차이는 간단한 연결을 수행 할 때 StringBuffer가 String보다 빠르다는 것입니다. 문자열 조작 코드에서 문자열은 일상적으로 연결됩니다. String 클래스를 사용하여 연결은 일반적으로 다음과 같이 수행됩니다.
String str = new String ("Stanford ");
str += "Lost!!";
StringBuffer를 사용하여 동일한 연결을 수행하려면 다음과 같은 코드가 필요합니다.
StringBuffer str = new StringBuffer ("Stanford ");
str.append("Lost!!");
개발자는 일반적으로 위의 첫 번째 예제가 더 효율적이라고 가정합니다. 연결을 위해 append 메서드를 사용하는 두 번째 예제가 + 연산자를 사용하여 두 String 개체를 연결하는 첫 번째 예제보다 비용이 더 많이 든다고 생각하기 때문입니다.
+ 연산자는 무해한 것처럼 보이지만 생성 된 코드는 놀라운 결과를 낳습니다. 연결에 StringBuffer를 사용하면 실제로 String을 사용하는 것보다 훨씬 빠른 코드를 생성 할 수 있습니다. 이것이 왜 그런지 알아 보려면 두 예제에서 생성 된 바이트 코드를 조사해야합니다. String을 사용하는 예제의 바이트 코드는 다음과 같습니다.
0 new #7 <Class java.lang.String>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1
위치 0에서 9까지의 바이트 코드는 코드의 첫 번째 줄에 대해 실행됩니다.
String str = new String("Stanford ");
그런 다음 위치 10에서 29까지의 바이트 코드가 연결을 위해 실행됩니다.
str += "Lost!!";
여기서 흥미로운 일이 생깁니다. 연결을 위해 생성 된 바이트 코드는 StringBuffer 객체를 생성 한 다음 해당 append 메소드를 호출합니다. 임시 StringBuffer 객체는 위치 10에서 생성되고 해당 append 메소드는 위치 23에서 호출됩니다. String 클래스는 변경 불가능하므로 StringBuffer를 사용해야합니다. 연쇄.
연결이 StringBuffer 개체에서 수행 된 후 다시 문자열로 변환되어야합니다. 이는 26 번 위치에서 toString 메소드를 호출하여 수행됩니다.이 메소드는 임시 StringBuffer 객체에서 새로운 String 객체를 생성합니다. 이 임시 StringBuffer 객체를 생성하고 이후에 String 객체로 다시 변환하는 데는 비용이 많이 듭니다.
요약하면 위의 두 줄의 코드는 세 개의 개체를 생성합니다.
- 위치 0의 문자열 객체
- 위치 10의 StringBuffer 객체
- 26 번 위치의 String 객체
이제 StringBuffer를 사용하여 예제를 위해 생성 된 바이트 코드를 살펴 보겠습니다.
0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop
위치 0에서 9까지의 바이트 코드는 코드의 첫 번째 줄에 대해 실행됩니다.
StringBuffer str = new StringBuffer("Stanford ");
그런 다음 위치 10에서 16까지의 바이트 코드가 연결을 위해 실행됩니다.
str.append("Lost!!");
첫 번째 예제의 경우와 같이이 코드는 StringBuffer 객체의 append 메서드를 호출합니다. 그러나 첫 번째 예제와 달리 임시 StringBuffer를 만든 다음 String 개체로 변환 할 필요가 없습니다. 이 코드는 위치 0에 하나의 객체 인 StringBuffer 만 만듭니다.
결론적으로 StringBuffer 연결은 String 연결보다 훨씬 빠릅니다. 분명히 StringBuffers는 가능한 경우 이러한 유형의 작업에 사용되어야합니다. String 클래스의 기능이 필요한 경우 연결에 StringBuffer를 사용한 다음 String으로 한 번의 변환을 수행하는 것이 좋습니다.
추가 작업도 증명 한 후 String / StringBuffer 개체의 해시 코드를 인쇄하면 String 개체가 동일한 String 개체를 사용하지 않고 매번 새로운 값으로 내부적으로 다시 생성됩니다.
public class MutableImmutable {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("String is immutable");
String s = "test";
System.out.println(s+"::"+s.hashCode());
for (int i = 0; i < 10; i++) {
s += "tre";
System.out.println(s+"::"+s.hashCode());
}
System.out.println("String Buffer is mutable");
StringBuffer strBuf = new StringBuffer("test");
System.out.println(strBuf+"::"+strBuf.hashCode());
for (int i = 0; i < 10; i++) {
strBuf.append("tre");
System.out.println(strBuf+"::"+strBuf.hashCode());
}
}
}
출력 : 해시 코드와 함께 개체 값을 인쇄합니다.
String is immutable
test::3556498
testtre::-1422435371
testtretre::-1624680014
testtretretre::-855723339
testtretretretre::2071992018
testtretretretretre::-555654763
testtretretretretretre::-706970638
testtretretretretretretre::1157458037
testtretretretretretretretre::1835043090
testtretretretretretretretretre::1425065813
testtretretretretretretretretretre::-1615970766
String Buffer is mutable
test::28117098
testtre::28117098
testtretre::28117098
testtretretre::28117098
testtretretretre::28117098
testtretretretretre::28117098
testtretretretretretre::28117098
testtretretretretretretre::28117098
testtretretretretretretretre::28117098
testtretretretretretretretretre::28117098
testtretretretretretretretretretre::28117098
A StringBuffer
또는 더 젊고 빠른 형제 StringBuilder
는 풍미에서 많은 문자열 연결을 할 때마다 선호됩니다.
string += newString;
또는 동등하게
string = string + newString;
위의 구성은 매번 새로운 문자열을 암시 적으로 생성하기 때문에 엄청난 성능과 저하가 발생합니다. A StringBuffer
/ StringBuilder
는 동적으로 확장 가능한 것과 비교하는 것이 가장 좋습니다 List<Character>
.
A String
는 변경 불가능한 문자 배열입니다.
A StringBuffer
는 가변 문자 배열입니다. 종종 String
돌연변이가 완료되면 다시 변환됩니다 .
Since both are an array, the maximum size for both is equal to the maximum size of an integer, which is 2^31-1 (see JavaDoc, also check out the JavaDoc for both String
and StringBuffer
).This is because the .length
argument of an array is a primitive int
. (See Arrays).
String is immutable, meaning that when you perform an operation on a String you are really creating a whole new String.
StringBuffer is mutable, and you can append to it as well as reset its length to 0.
In practice, the compiler seems to use StringBuffer during String concatenation for performance reasons.
String is immutable.
Why? Check here.
StringBuffer is not. It is thread safe.
Further questions like when to use which and other concepts can be figured out following this.
Hope this helps.
While I understand that this is not a major differentiating factor, I noticed today that StringBuffer(and StringBuilder) provides some interesting methods that String doesn't.
- reverse()
- setCharAt()
The differences are
- Only in String class + operator is overloaded. We can concat two String object using + operator, but in the case of StringBuffer we can't.
String class is overriding toString(), equals(), hashCode() of Object class, but StringBuffer only overrides toString().
String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.equals(s2)); // output true StringBuffer sb1 = new StringBuffer("abc"); StringBuffer sb2 = new StringBuffer("abc"); System.out.println(sb1.equals(sb2)); // output false
String class is both Serializable as well as Comparable, but StringBuffer is only Serializable.
Set<StringBuffer> set = new TreeSet<StringBuffer>(); set.add(sb1); set.add(sb2); System.out.println(set); // gives ClassCastException because there is no Comparison mechanism
We can create a String object with and without new operator, but StringBuffer object can only be created using new operator.
- String is immutable but StringBuffer is mutable.
- StringBuffer is synchronized, whereas String ain't.
- StringBuffer is having an in-built reverse() method, but String dosen't have it.
Performance wise StringBuffer is much better than String ; because whenever you apply concatenation on String Object then new String object are created on each concatenation.
Principal Rule : String are immutable(Non Modifiable) and StringBuffer are mutable(Modifiable)
Here is the programmatic experiment where you get the performance difference
public class Test {
public static int LOOP_ITERATION= 100000;
public static void stringTest(){
long startTime = System.currentTimeMillis();
String string = "This";
for(int i=0;i<LOOP_ITERATION;i++){
string = string+"Yasir";
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
public static void stringBufferTest(){
long startTime = System.currentTimeMillis();
StringBuffer stringBuffer = new StringBuffer("This");
for(int i=0;i<LOOP_ITERATION;i++){
stringBuffer.append("Yasir");
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
public static void main(String []args){
stringTest()
stringBufferTest();
}
}
Output of String are in my machine 14800
Output of StringBuffer are in my machine 14
'program tip' 카테고리의 다른 글
Perl에서 my와 local의 차이점은 무엇입니까? (0) | 2020.11.23 |
---|---|
SICP를 통해 작업하기위한 최상의 Scheme 구현은 무엇입니까? (0) | 2020.11.23 |
두 벡터 사이의 시계 방향 각도를 직접 계산하는 방법 (0) | 2020.11.23 |
PIL에서 openCV 형식으로 이미지 변환 (0) | 2020.11.23 |
다른 사람의 Github에서 리포지토리를 복제하여 내 Github의 리포지토리로 푸시 (0) | 2020.11.23 |