Java의 String과 StringBuffer의 차이점은 무엇입니까?
-
19-09-2019 - |
문제
Java의 String과 StringBuffer의 차이점은 무엇입니까?
문자열의 최대 크기가 있습니까?
해결책
String
변경할 수없는 문자열을 조작하는 데 사용됩니다 (읽기 전용 및 불변).
StringBuffer
수정할 수있는 문자를 나타내는 데 사용됩니다.
성능 현명한, StringBuffer
연결을 수행 할 때 더 빠릅니다. 이것은 당신이 연결할 때 a String
, 당신은 이후 매번 (내부적으로) 새 개체를 만들고 있습니다. String
불변입니다.
당신은 또한 사용할 수 있습니다 StringBuilder
비슷합니다 StringBuffer
동기화되지 않은 경우를 제외하고. 이 중 하나의 최대 크기는입니다 Integer.MAX_VALUE
(231 -1 = 2,147,483,647) 또는 최대 힙 크기는 2로 나뉩니다 (참조 Java String은 몇 개의 문자를 가질 수 있습니까?). 추가 정보 여기.
다른 팁
ㅏ String
불변, 즉 만들어 졌을 때 결코 변할 수 없습니다.
ㅏ StringBuffer
(또는 동기화되지 않은 사촌 StringBuilder
) 작은 구조의 성능 오버 헤드없이 문자열을 조각별로 만들어야 할 때 사용됩니다. String
길을 따라 s.
두 가지의 최대 길이는 정수입니다 .max_value는 내부적으로 배열로 저장되고 Java 어레이는 int
그들의 길이가 유사비.
성능 향상 String
모래 StringBuffer
다중 연결의 경우 S는 상당히 중요합니다. 다음 테스트 코드를 실행하면 차이가 표시됩니다. Java 6이있는 고대 노트북에서는 다음과 같은 결과를 얻습니다.
Concat with String took: 1781ms Concat with StringBuffer took: 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"데이터를 복사하고 "세계"를 복사하면서 새로운 메모리를 모두 재 할당하고 있습니다! 결국,이 새로운 메모리를 가리 키도록 str1 참조를 설정합니다. 그래서 그것은 정말로 이렇게 보입니다.
String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;
따라서이 "복사 + 붙여 넣기 및 메모리에서 물건을 이동"프로세스는 반복적으로 재귀 적으로 완료되면 매우 비쌀 수 있습니다.
당신이 그런 상황에있을 때, StringBuilder를 계속해서 사용해야합니다. 그것은 변이 가능하며 현장의 끝까지 문자열을 추가 할 수 있습니다. [실제 데이터 구조 인 경우 100%가 아님) 목록이 될 수 있기 때문입니다.
로부터 API :
스레드 안전, 변이 가능한 문자 순서. 문자열 버퍼는 문자열과 같지만 수정할 수 있습니다. 언제든지 특정 문자 순서가 포함되어 있지만 시퀀스의 길이와 내용은 특정 메소드 호출을 통해 변경 될 수 있습니다.
StringBuffer는 많은 문자열에서 단일 문자열을 만드는 데 사용됩니다. 예를 들어 루프에서 문자열의 일부를 추가하려면.
StringBuilder가 동기화되지 않아 빠르지 않기 때문에 StringBuffer에 단일 스레드 만 액세스하는 경우 StringBuffer 대신 StringBuilder를 사용해야합니다.
afaik Java에서 언어로 문자열 크기의 상한은 없지만 JVM은 아마도 상한이있을 것입니다.
Reggie Hutcherso의 비교 성능 문자열 대 StringBuffer에 대한 관심 답변을 찾았습니다.원천: http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html
Java는 StringBuffer 및 String 클래스를 제공하며 String 클래스는 변경할 수없는 문자열을 조작하는 데 사용됩니다. 간단히 말하면, 유형 문자열의 객체는 읽고 불변입니다. StringBuffer 클래스는 수정할 수있는 문자를 나타내는 데 사용됩니다.
이 두 클래스의 중요한 성능 차이점은 간단한 연결을 수행 할 때 StringBuffer가 String보다 빠르다는 것입니다. 문자열 조작 코드에서 문자열이 일상적으로 연결됩니다. 문자열 클래스를 사용하여 연결은 일반적으로 다음과 같이 수행됩니다.
String str = new String ("Stanford ");
str += "Lost!!";
StringBuffer를 사용하여 동일한 연결을 수행하려면 다음과 같은 코드가 필요합니다.
StringBuffer str = new StringBuffer ("Stanford ");
str.append("Lost!!");
개발자는 일반적으로 위의 첫 번째 예제가 연결을 위해 첨부 방법을 사용하는 두 번째 예제가 + 연산자를 사용하여 두 개의 문자열 객체를 연결하는 첫 번째 예보다 비용이 많이 든다고 생각하기 때문에 위의 첫 번째 예제가 더 효율적이라고 가정합니다.
+ 연산자는 결백하게 보이지만 생성 된 코드는 놀라운 일을 생성합니다. 연결을 위해 StringBuffer를 사용하면 실제로 문자열을 사용하는 것보다 훨씬 빠른 코드를 생성 할 수 있습니다. 이것이 왜 그런지 알기 위해서는 두 예제에서 생성 된 바이트 코드를 검사해야합니다. 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에서 호출됩니다. 문자열 클래스는 불변이기 때문에 StringBuffer를 사용해야합니다. 연쇄.
StringBuffer 객체에서 연결을 수행 한 후에는 문자열로 다시 변환해야합니다. 이것은 위치 26에서 Tostring 메소드로 호출하여 수행됩니다.이 방법은 임시 StringBuffer 객체에서 새 문자열 객체를 만듭니다. 이 임시 StringBuffer 객체의 생성과 그 이후의 스트링 객체로 다시 변환하는 것은 매우 비쌉니다.
요약하면, 위의 두 줄의 코드는 세 가지 개체를 생성합니다.
- 위치 0의 문자열 객체
- 위치 10의 StringBuffer 객체
- 위치 26의 문자열 객체
이제 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를 만들어 문자열 객체로 변환 할 필요가 없습니다. 이 코드는 위치 0에서 하나의 객체 인 StringBuffer 만 생성합니다.
결론적으로, StringBuffer 연결은 문자열 연결보다 훨씬 빠릅니다. 분명히, StringBuffers는 가능한 경우 이러한 유형의 작업에 사용해야합니다. 문자열 클래스의 기능이 원하는 경우, 연결을 위해 StringBuffer를 사용한 다음 String으로 하나의 변환을 수행하는 것을 고려하십시오.
첨부 작업이 증명 된 후 String/StringBuffer 객체의 해시 코드를 인쇄함으로써 String Object는 동일한 문자열 객체를 사용하지 않고 새 값으로 매번 내부적으로 재현됩니다.
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
ㅏ StringBuffer
또는 더 젊고 빠른 형제 StringBuilder
당신이 맛의 많은 문자열 연결을 할 때마다 선호됩니다.
string += newString;
또는 동등하게
string = string + newString;
위의 구성이 암시 적으로 생성되기 때문입니다 새로운 매번 문자열은 큰 성능과 드롭이 될 것입니다. ㅏ StringBuffer
/ StringBuilder
동적으로 확장 가능한 것과 비교하는 것이 가장 좋은 후드 아래에 있습니다. List<Character>
.
문자열은 불변이기 때문에 문자열에서 작업을 수행 할 때 완전히 새 문자열을 생성한다는 의미입니다.
StringBuffer 변이 가능하며, 길이를 0으로 재설정 할뿐만 아니라 추가 할 수 있습니다.
실제로, 컴파일러는 문자열 연결 중에 StringBuffer를 사용하는 것 같습니다. 성능 이유로.
나는 이것이 주요 차별화 요소가 아니라는 것을 이해하지만 오늘날 StringBuffer (및 StringBuilder)는 String이 그렇지 않은 흥미로운 방법을 제공한다는 것을 알았습니다.
- 뒤집다()
- setcharat ()
차이점이 있습니다
- 만 끈 수업 + 연산자가 과부하되었습니다. 우리는 두 개의 문자열 객체를 사용하여 연결할 수 있습니다 + 운영자이지만 경우 StringBuffer 우리는 할 수 없습니다.
끈 클래스는 toString (), equals (), hashcode ()를 우선시합니다. 물체 수업, 그러나 StringBuffer 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
끈 수업은 둘 다입니다 직렬화 가능 만큼 잘 유사한, 하지만 StringBuffer 오직 직렬화 가능.
Set<StringBuffer> set = new TreeSet<StringBuffer>(); set.add(sb1); set.add(sb2); System.out.println(set); // gives ClassCastException because there is no Comparison mechanism
우리는 또는없이 문자열 객체를 만들 수 있습니다 새로운 연산자이지만 StringBuffer 객체는 새로운 운영자.
- 문자열은 불변이지만 StringBuffer는 변동성이 있습니다.
- StringBuffer는 동기화되지만 String은 그렇지 않습니다.
- StringBuffer는 제작되었습니다 뒤집다() 방법이지만 문자열은 그것을 가지고 있지 않습니다.
성능 현명한 StringBuffer는 문자열보다 훨씬 낫습니다. 문자열 객체에 연결을 적용 할 때마다 각 연결에 새 문자열 객체가 생성됩니다.
주요 규칙 : 문자열은 불변 (수정할 수 없음)이고 StringBuffer는 Mutable (수정 가능)입니다.
성능 차이를 얻는 프로그램 실험은 다음과 같습니다.
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();
}
}
문자열 출력이 내 컴퓨터에 있습니다 14800
StringBuffer의 출력이 내 컴퓨터에 있습니다 14