Java String、StringBuffer、StringBuilderの違い
26123 ワード
Javaで文字列を作成する3つの方法を見てみましょう.String、StringBuffer、StringBuilderです.
0、概要
重複除外によるメモリ使用率の向上
重複文字列を複数回作成すると、新しいオブジェクトを作成することなく、リファレンスによってメモリ効率を向上させることができます. スレッドセキュリティ
String値を同時に参照しても更新できないため、複数のねじが常に同じ値であることを確認します.
文字列の変更が多すぎると、新しいオブジェクトを作成し続けるとメモリの使用効率が低下します.
新しい文字列が既存の文字列に追加され続ける場合、
これにより、不要なオブジェクトが大量に生成され、メモリの使用率が向上します.
文字列を変更する必要がある場合は、 を追加してメモリ効率を向上させることができます.
3.スレッドセキュリティ
0、概要
結論から言えば、次は一つ一つ理解してみましょう.
1.文字列生成方式
不変性と可変性を理解するには、その作成方法を理解する必要があります.
1) String
Stringクラスを使用して文字列を作成する方法は、大きく2つあります.1) 리터럴 방식 (쌍따옴표) 2) 생성자 방식
メモリの使用効率が低いため、ジェネレータメソッドはあまり使いにくい.
したがって、String은 리터럴 방식
を使用すると仮定します.
テキスト方式(二重引用符)
Javaでは、""
の二重引用符文字列を作成する方法を리터럴 방식
と呼びます.
文字方式は、まずHeapのString Constant Poolを検索し、hello文字列を検索します.ない場合は作成し、ある場合はアドレス値を参照し、作成しません.class Main {
public static void main(String[] args) {
// 1) 리터럴 방식
// String constant Pool에 hello 저장
String a = "hello";
// 이미 저장된 hello 참조
String b = "hello";
System.out.println(a == b); // 주소비교 true
System.out.println(a.equals(b)); // 값 비교 true
}
}
ジェネレータモード
新しいオブジェクトを作成してheapに保存するたびに.
メモリ管理もString Constant Pool
では行えないため、効率が悪い.class Main {
public static void main(String[] args) {
// 생성자 방식
// heap에 hello 문자열 저장
String a = new String("hello");
// heap에 hello 문자열 저장
String b = new String("hello");
System.out.println(a == b); // 주소비교 false
System.out.println(a.equals(b)); // 값 비교 true
}
}
2) StringBuffer, StringBuilder
StringBufferとStringBuilderの作成方法は同じです.
16個の連続メモリ領域が最初に割り当てられます.領域を超えると、より長い連続メモリ領域が割り当てられ、以前の内容がコピーされます.
2.不変、可変
1)定義
不変、可変の意味は次のとおりです.불변
は現在参照されている주소의 값이 변하지 않음
を表し、가변
は現在参照されている참조하고 있는 값이 변할 수 있음
を表している.
2) String
Stringは、新しい文字列を置換するときに古い参照値を破棄し、新しいアドレスを参照します.
class Main {
public static void main(String[] args) {
// a - "hello" 참조
String a = "hello";
// b - "hello" 참조
String b = a;
// a - 새로운 객체 "hello world" 참조 - "hello"는 더이상 참조하지 않음
a += " world";
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello" 참조
System.out.println("b " + b);
}
}
3) StringBuffer, StringBuilder
現在のアドレス値から新しい文字列を追加した後、連続メモリ領域に追加します.
ArrayList.class Main {
public static void main(String[] args) {
// a - "hello" 참조
StringBuffer a = new StringBuffer("hello");
// b - "hello" 참조
StringBuffer b = a;
// a - "hello world" 참조, 참조하는 주소의 값이 변경된 경우
a.append(" world");
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello world" 참조
System.out.println("b " + b);
}
}
4)整理
長所
不変性と可変性を理解するには、その作成方法を理解する必要があります.
1) String
Stringクラスを使用して文字列を作成する方法は、大きく2つあります.
1) 리터럴 방식 (쌍따옴표) 2) 생성자 방식
メモリの使用効率が低いため、ジェネレータメソッドはあまり使いにくい.したがって、
String은 리터럴 방식
を使用すると仮定します.テキスト方式(二重引用符)
Javaでは、
""
の二重引用符文字列を作成する方法を리터럴 방식
と呼びます.文字方式は、まずHeapのString Constant Poolを検索し、hello文字列を検索します.ない場合は作成し、ある場合はアドレス値を参照し、作成しません.
class Main {
public static void main(String[] args) {
// 1) 리터럴 방식
// String constant Pool에 hello 저장
String a = "hello";
// 이미 저장된 hello 참조
String b = "hello";
System.out.println(a == b); // 주소비교 true
System.out.println(a.equals(b)); // 값 비교 true
}
}
ジェネレータモード
新しいオブジェクトを作成してheapに保存するたびに.
メモリ管理も
String Constant Pool
では行えないため、効率が悪い.class Main {
public static void main(String[] args) {
// 생성자 방식
// heap에 hello 문자열 저장
String a = new String("hello");
// heap에 hello 문자열 저장
String b = new String("hello");
System.out.println(a == b); // 주소비교 false
System.out.println(a.equals(b)); // 값 비교 true
}
}
2) StringBuffer, StringBuilder
StringBufferとStringBuilderの作成方法は同じです.
16個の連続メモリ領域が最初に割り当てられます.領域を超えると、より長い連続メモリ領域が割り当てられ、以前の内容がコピーされます.
2.不変、可変
1)定義
不変、可変の意味は次のとおりです.불변
は現在参照されている주소의 값이 변하지 않음
を表し、가변
は現在参照されている참조하고 있는 값이 변할 수 있음
を表している.
2) String
Stringは、新しい文字列を置換するときに古い参照値を破棄し、新しいアドレスを参照します.
class Main {
public static void main(String[] args) {
// a - "hello" 참조
String a = "hello";
// b - "hello" 참조
String b = a;
// a - 새로운 객체 "hello world" 참조 - "hello"는 더이상 참조하지 않음
a += " world";
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello" 참조
System.out.println("b " + b);
}
}
3) StringBuffer, StringBuilder
現在のアドレス値から新しい文字列を追加した後、連続メモリ領域に追加します.
ArrayList.class Main {
public static void main(String[] args) {
// a - "hello" 참조
StringBuffer a = new StringBuffer("hello");
// b - "hello" 참조
StringBuffer b = a;
// a - "hello world" 참조, 참조하는 주소의 값이 변경된 경우
a.append(" world");
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello world" 참조
System.out.println("b " + b);
}
}
4)整理
長所
class Main {
public static void main(String[] args) {
// a - "hello" 참조
String a = "hello";
// b - "hello" 참조
String b = a;
// a - 새로운 객체 "hello world" 참조 - "hello"는 더이상 참조하지 않음
a += " world";
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello" 참조
System.out.println("b " + b);
}
}
class Main {
public static void main(String[] args) {
// a - "hello" 참조
StringBuffer a = new StringBuffer("hello");
// b - "hello" 참조
StringBuffer b = a;
// a - "hello world" 참조, 참조하는 주소의 값이 변경된 경우
a.append(" world");
// a는 "hello world" 참조
System.out.println("a " + a);
// b는 "hello world" 참조
System.out.println("b " + b);
}
}
重複文字列を複数回作成すると、新しいオブジェクトを作成することなく、リファレンスによってメモリ効率を向上させることができます.
String値を同時に参照しても更新できないため、複数のねじが常に同じ値であることを確認します.
不変の欠点
文字列の変更が多すぎると、新しいオブジェクトを作成し続けるとメモリの使用効率が低下します.
新しい文字列が既存の文字列に追加され続ける場合、
String
は古い参照オブジェクトを破棄し続け、参照用に新しいオブジェクトを作成します.これにより、不要なオブジェクトが大量に生成され、メモリの使用率が向上します.
class Main {
public static void main(String[] args) {
String a = "";
for(int i=0; i<100000; i++) {
// 새로운 객체 참조
a += "";
}
}
}
可変のメリット
3.スレッドセキュリティ
1)定義
スレッドセキュリティは、複数のスレッドに同時にアクセスしてもプログラムの動作に問題が発生しないことを意味します.
2)スレッドセキュリティ
String
変化しないため、いずれの場合も同じ値であることを確認します.
StringBuffer
複数のスレッドがsynchronizedキーワードで同時にアクセスされている場合は、一度に1つのスレッドしか使用できず、スレッドのセキュリティが確保されます.
StringBuilder
スレッドセキュリティはまったく設定されません.
4.演算速度
0)概要
String-遅い-O(xn^2)-xは連続文字の長さ、nはカウント
StringBuffer-中間-O(xn)
StringBuilder-高速-O(xn)
1) String
最大백만번
の追加演算1156ms
が必要です.
Stringは+演算を実行するたびに新しい文字列をコピーします.
1 + 2 + .... n=n(n+1),O(xn^2).class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
String a = "";
for(int i=0; i<1000000; i++) {
a += "a";
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
2) StringBuffer
追加演算1억번
は、951ms
を必要とする.class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0; i<100000000; i++) {
sb.append("a");
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
3) StringBuilder
追加演算1억번
は、371ms
を必要とする.class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for(int i=0; i<100000000; i++) {
sb.append("a");
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
5.整理
だからいつ何を使うかが一番重要です
String
少量の文字列追加と重複除外が必要なスレッドセキュリティ環境
StringBuffer
文字列付加操作の多いスレッドセキュリティ環境
StringBuilder
マルチスレッド環境では、スレッドセキュリティを考慮する必要はほとんどありません.
本当に、例えば、アルゴリズムを解く
最近はあまり流行していませんが、以前は文字列入力を直接受信して処理することがよくありました.
BufferedReaderアクセラレータを使用し、BufferedReaderは内部で文字列を受信するときにStringBuilderを使用します.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 문자열 한줄 읽기
int n = Integer.parseInt(br.readLine());
}
}
Reference
この問題について(Java String、StringBuffer、StringBuilderの違い), 我々は、より多くの情報をここで見つけました
https://velog.io/@skyepodium/자바-String-StringBuffer-StringBuilder-차이점
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
0)概要
String-遅い-O(xn^2)-xは連続文字の長さ、nはカウント
StringBuffer-中間-O(xn)
StringBuilder-高速-O(xn)
1) String
最大
백만번
の追加演算1156ms
が必要です.Stringは+演算を実行するたびに新しい文字列をコピーします.
1 + 2 + .... n=n(n+1),O(xn^2).
class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
String a = "";
for(int i=0; i<1000000; i++) {
a += "a";
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
2) StringBuffer
追加演算
1억번
は、951ms
を必要とする.class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0; i<100000000; i++) {
sb.append("a");
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
3) StringBuilder
追加演算
1억번
は、371ms
を必要とする.class Main {
public static void main(String[] args) {
long beforeTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for(int i=0; i<100000000; i++) {
sb.append("a");
}
long afterTime = System.currentTimeMillis();
long secDiffTime = (afterTime - beforeTime);
System.out.println("시간차이(ms) : "+secDiffTime);
}
}
5.整理
だからいつ何を使うかが一番重要です
String
少量の文字列追加と重複除外が必要なスレッドセキュリティ環境
StringBuffer
文字列付加操作の多いスレッドセキュリティ環境
StringBuilder
マルチスレッド環境では、スレッドセキュリティを考慮する必要はほとんどありません.
本当に、例えば、アルゴリズムを解く
最近はあまり流行していませんが、以前は文字列入力を直接受信して処理することがよくありました.
BufferedReaderアクセラレータを使用し、BufferedReaderは内部で文字列を受信するときにStringBuilderを使用します.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 문자열 한줄 읽기
int n = Integer.parseInt(br.readLine());
}
}
Reference
この問題について(Java String、StringBuffer、StringBuilderの違い), 我々は、より多くの情報をここで見つけました
https://velog.io/@skyepodium/자바-String-StringBuffer-StringBuilder-차이점
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 문자열 한줄 읽기
int n = Integer.parseInt(br.readLine());
}
}
Reference
この問題について(Java String、StringBuffer、StringBuilderの違い), 我々は、より多くの情報をここで見つけました https://velog.io/@skyepodium/자바-String-StringBuffer-StringBuilder-차이점テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol