Java의 toString()에서 StringBuilder 대 String 연결
두 개로 나눠서toString()
아래 구현 중 선호되는 구현:
public String toString(){
return "{a:"+ a + ", b:" + b + ", c: " + c +"}";
}
또는
public String toString(){
StringBuilder sb = new StringBuilder(100);
return sb.append("{a:").append(a)
.append(", b:").append(b)
.append(", c:").append(c)
.append("}")
.toString();
}
?
더 중요한 것은, 우리가 단지 3개의 속성을 가지고 있기 때문에, 그것은 차이를 만들 수 없을 수도 있지만, 어느 시점에서 당신은 전환하시겠습니까?+
에 연결하다.StringBuilder
?
버전 1은 더 짧고 컴파일러가 실제로 버전 2로 전환하기 때문에 성능 차이가 전혀 없기 때문에 더 바람직하다.
더 중요한 것은 우리가 단지 3개의 특성만 가지고 있기 때문에 차이가 나지 않을 수도 있지만, 어느 시점에 당신은 concat에서 builder로 바꾸는가?
- 가 루로 때 이다StringBuilder
저절로
관건은 한 곳에 한 군데를 통째로 쓰는 것인지, 아니면 시간이 흐르면서 쌓이는 것인지입니다.
예를 들어 StringBuilder를 명시적으로 사용하는 것은 의미가 없다.(첫 번째 사례에 대해 컴파일된 코드를 보십시오.)
그러나 루프 내부에서 문자열을 작성하는 경우에는 StringBuilder를 사용하십시오.
largeArray에 수천 개의 문자열이 포함되어 있다고 가정하면 다음과 같은 코드를 입력하십시오.
...
String result = "";
for (String s : hugeArray) {
result = result + s;
}
다음과 비교하여 매우 시간 및 기억력이 높다.
...
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
sb.append(s);
}
String result = sb.toString();
대부분의 경우, 두 가지 접근방식의 실제 차이는 나타나지 않지만, 다음과 같은 최악의 시나리오를 구성하기는 쉽다.
public class Main
{
public static void main(String[] args)
{
long now = System.currentTimeMillis();
slow();
System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");
now = System.currentTimeMillis();
fast();
System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
}
private static void fast()
{
StringBuilder s = new StringBuilder();
for(int i=0;i<100000;i++)
s.append("*");
}
private static void slow()
{
String s = "";
for(int i=0;i<100000;i++)
s+="*";
}
}
출력:
slow elapsed 11741 ms
fast elapsed 7 ms
문제는 끈에 +=를 추가하면 새로운 문자열이 재구성되기 때문에 문자열 길이에 선형적인 비용이 든다는 것이다(두 문자열의 합).
따라서 - 질문에 대해 다음과 같이 답하십시오.
두 번째 접근 방식은 더 빠르겠지만 읽기 쉽고 유지하기가 더 어렵다.내가 말했듯이, 너의 구체적인 경우에는 아마 차이를 보지 못할 것이다.
나는 다음을 선호한다.
String.format( "{a: %s, b: %s, c: %s}", a, b, c );
짧고 읽기 쉬우니까
반복 횟수가 매우 높은 루프 내에서 사용하고 성능 차이를 측정하지 않는 한 이 속도를 위해 최적화하지 않을 것이다.
나도 동의해, 만약 당신이 많은 파라미터를 출력해야 한다면, 이 양식은 혼란스러워질 수 있어. (댓글 중 하나가 말한 것처럼)이 경우 좀 더 읽기 쉬운 형식(아마도 매트 b의 답변에서 가져온 아파치 코먼의 ToStringBuilder 사용)으로 전환하고 성능을 다시 무시한다.
Java 1.5 이후, "+"와 StringBuilder.append()와 간단한 한 줄 연결은 정확히 동일한 바이트 코드를 생성한다.
따라서 코드 가독성을 위해 "+"를 사용하십시오.
2개의 예외:
- 멀티스레드 환경 : StringBuffer
- 루프 연결 : StringBuilder/StringBuffer
나는 또한 나의 상사와 부록 또는 +를 사용할 것인지에 대해 충돌했다.그들이 Add(나는 여전히 새로운 물체가 만들어질 때마다 그들이 말하는 것처럼 이해할 수 없다.)를 사용하고 있기 때문이다.그래서 나는 R&D를 좀 해볼까 생각했어.비록 나는 마이클 보그워트의 설명을 사랑하지만, 단지 누군가가 미래에 정말로 알아야 할 필요가 있는지 설명을 보여주고 싶었을 뿐이다.
/**
*
* @author Perilbrain
*/
public class Appc {
public Appc() {
String x = "no name";
x += "I have Added a name" + "We May need few more names" + Appc.this;
x.concat(x);
// x+=x.toString(); --It creates new StringBuilder object before concatenation so avoid if possible
//System.out.println(x);
}
public void Sb() {
StringBuilder sbb = new StringBuilder("no name");
sbb.append("I have Added a name");
sbb.append("We May need few more names");
sbb.append(Appc.this);
sbb.append(sbb.toString());
// System.out.println(sbb.toString());
}
}
그리고 위 등급의 분해는 다음과 같이 나온다.
.method public <init>()V //public Appc()
.limit stack 2
.limit locals 2
met001_begin: ; DATA XREF: met001_slot000i
.line 12
aload_0 ; met001_slot000
invokespecial java/lang/Object.<init>()V
.line 13
ldc "no name"
astore_1 ; met001_slot001
.line 14
met001_7: ; DATA XREF: met001_slot001i
new java/lang/StringBuilder //1st object of SB
dup
invokespecial java/lang/StringBuilder.<init>()V
aload_1 ; met001_slot001
invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
ldc "I have Added a nameWe May need few more names"
invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
aload_0 ; met001_slot000
invokevirtual java/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lan\
g/StringBuilder;
invokevirtual java/lang/StringBuilder.toString()Ljava/lang/String;
astore_1 ; met001_slot001
.line 15
aload_1 ; met001_slot001
aload_1 ; met001_slot001
invokevirtual java/lang/String.concat(Ljava/lang/String;)Ljava/lang/Strin\
g;
pop
.line 18
return //no more SB created
met001_end: ; DATA XREF: met001_slot000i ...
; ===========================================================================
;met001_slot000 ; DATA XREF: <init>r ...
.var 0 is this LAppc; from met001_begin to met001_end
;met001_slot001 ; DATA XREF: <init>+6w ...
.var 1 is x Ljava/lang/String; from met001_7 to met001_end
.end method
;44-1=44
; ---------------------------------------------------------------------------
; Segment type: Pure code
.method public Sb()V //public void Sb
.limit stack 3
.limit locals 2
met002_begin: ; DATA XREF: met002_slot000i
.line 21
new java/lang/StringBuilder
dup
ldc "no name"
invokespecial java/lang/StringBuilder.<init>(Ljava/lang/String;)V
astore_1 ; met002_slot001
.line 22
met002_10: ; DATA XREF: met002_slot001i
aload_1 ; met002_slot001
ldc "I have Added a name"
invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
pop
.line 23
aload_1 ; met002_slot001
ldc "We May need few more names"
invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
pop
.line 24
aload_1 ; met002_slot001
aload_0 ; met002_slot000
invokevirtual java/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lan\
g/StringBuilder;
pop
.line 25
aload_1 ; met002_slot001
aload_1 ; met002_slot001
invokevirtual java/lang/StringBuilder.toString()Ljava/lang/String;
invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
pop
.line 28
return
met002_end: ; DATA XREF: met002_slot000i ...
;met002_slot000 ; DATA XREF: Sb+25r
.var 0 is this LAppc; from met002_begin to met002_end
;met002_slot001 ; DATA XREF: Sb+9w ...
.var 1 is sbb Ljava/lang/StringBuilder; from met002_10 to met002_end
.end method
;96-49=48
; ---------------------------------------------------------------------------
위의 두 가지 코드에서 당신은 마이클이 옳다는 것을 알 수 있다.각 경우 SB 개체는 하나만 생성된다.
를 최 )를 한다.javap -c
를 나타낸다는 컴파일러가 도입한 최적화를 나타낸다.+
뿐만 아니라.sb.append()
매우 유사한 코드가 생성될 것이다.그러나 만약 우리가 사용한다면, 그 행동을 점검해 볼 가치가 있을 것이다.+
구보로
루프에 +를 사용하여 문자열 추가
Java:
public String myCatPlus(String[] vals) {
String result = "";
for (String val : vals) {
result = result + val;
}
return result;
}
바이트코드:()for
반복 발췌)
12: iload 5
14: iload 4
16: if_icmpge 51
19: aload_3
20: iload 5
22: aaload
23: astore 6
25: new #3 // class java/lang/StringBuilder
28: dup
29: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
32: aload_2
33: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: aload 6
38: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_2
45: iinc 5, 1
48: goto 12
stringbuilder.append를 사용하여 문자열 추가
Java:
public String myCatSb(String[] vals) {
StringBuilder sb = new StringBuilder();
for(String val : vals) {
sb.append(val);
}
return sb.toString();
}
ByteCdoe:()for
반복 발췌)
17: iload 5
19: iload 4
21: if_icmpge 43
24: aload_3
25: iload 5
27: aaload
28: astore 6
30: aload_2
31: aload 6
33: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: pop
37: iinc 5, 1
40: goto 17
43: aload_2
그러나 약간의 현저한 차이가 있다.첫 번째 경우, 어디에+
사용되었다, 새로운StringBuilder
각 루프 반복에 대해 생성되며 생성된 결과는 다음 작업을 수행하여 저장된다.toString()
전화(29~41)하다.따라서 사용하는 동안 실제로 필요하지 않은 중간 문자열을 생성하는 경우+
을 교환하다.for
고리를 틀다
끈의 크기에 따라 달라진다.
아래 예제를 참조하십시오.
static final int MAX_ITERATIONS = 50000;
static final int CALC_AVG_EVERY = 10000;
public static void main(String[] args) {
printBytecodeVersion();
printJavaVersion();
case1();//str.concat
case2();//+=
case3();//StringBuilder
}
static void case1() {
System.out.println("[str1.concat(str2)]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
String str = "";
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str = str.concat(UUID.randomUUID() + "---");
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void case2() {
System.out.println("[str1+=str2]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
String str = "";
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str += UUID.randomUUID() + "---";
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void case3() {
System.out.println("[str1.append(str2)]");
List<Long> savedTimes = new ArrayList();
long startTimeAll = System.currentTimeMillis();
StringBuilder str = new StringBuilder("");
for (int i = 0; i < MAX_ITERATIONS; i++) {
long startTime = System.currentTimeMillis();
str.append(UUID.randomUUID() + "---");
saveTime(savedTimes, startTime);
}
System.out.println("Created string of length:" + str.length() + " in " + (System.currentTimeMillis() - startTimeAll) + " ms");
}
static void saveTime(List<Long> executionTimes, long startTime) {
executionTimes.add(System.currentTimeMillis() - startTime);
if (executionTimes.size() % CALC_AVG_EVERY == 0) {
out.println("average time for " + executionTimes.size() + " concatenations: "
+ NumberFormat.getInstance().format(executionTimes.stream().mapToLong(Long::longValue).average().orElseGet(() -> 0))
+ " ms avg");
executionTimes.clear();
}
}
출력:
자바 바이트코드 버전:8
java.version: 1.8.0_properties
)][str1.propert(str2)]
평균 0.096ms avg10000에 따라 시: 0.096ms avg
0 avg10000에 따라 최대 시 0: 0.130ms 평균
0 avg10000에 따라 최대 시: 0.327ms avg
0 avg10000에 따라 시: 0.51ms avg
avg10000에 따라 최대 시: 0.656ms avg
길이 문자열 생성:17745ms 1950000
[str1+=str2]
0 avg10000에 따라 최대 시: 0.21ms avg
avg10000에 따라 최대 시: 0.652ms 평균
1. avg10000에 따라 시 1.125ms 평균
avg10000 00의 평균 시 1.727ms 평균
avg10000에 따라 최대 시: 2.302ms avg
길이 문자열 생성:1950000(60279ms)
str1.properties(str2)]
avg10000에 따라 최대 시: 0.002ms avg
avg10000에 따라 최대 시: 0.002ms avg
avg10000에 따라 최대 시: 0.002ms avg
avg10000에 따라 최대 시: 0.002ms avg
avg10000에 따라 최대 시: 0.002ms avg
길이 문자열 생성:1950000(100ms)
끈 길이가 늘어남에 따라, 끈의 길이도 늘어나게 된다.+=
그리고.concat
결합 시간, 후자가 더 효율적이긴 하지만 여전히 비응급적이다.
그곳이 바로 그 곳이다.StringBuilder
반드시 필요하다.
추신: 나는 Java에서 StringBuilder를 언제 사용할지가 정말 이것의 복제품이라고 생각하지 않아.
이 질문은 에 대해 이야기한다.toString()
대부분의 경우 큰 현을 연결하지 않는다.
2019년 업데이트
이후java8
시대가 변했어.의 인 것 .+=
와 실질적으로 같다str.concat()
. 그러나 연결 시간은 여전히 일정하다. (위의 원본 포스트는 장황한 출력을 추가하기 위해 약간 편집되었다.)
자바 바이트 코드 버전:13
java.version: 13.0.1
)][str1.propert(str2)]
0 avg10000에 따라 최대 시: 0.047ms 평균
0 avg10000에 따라 최대 시: 0.1ms avg
0 avg10000에 따라 최대 시: 0.17ms avg
0 avg10000에 따라 최대 시 0: 0.130ms 평균
0 avg10000에 따라 최대 시: 0.336ms avg
길이 문자열 생성:1950000(9147ms)
[str1+=str2]
0 avg10000에 따라 평균: 0.037ms 평균
0 avg10000에 따라 시: 0.097ms 평균
0 avg10000에 따라 최대 시: 0.249ms avg
0 avg10000에 따라 최대 시: 0.298ms avg
0 avg10000에 따라 최대 시: 0.326ms avg
길이 문자열 생성:1950000(10191ms)
str1.properties(str2)]
avg10000에 따라 최대 시: 0.001ms avg
avg10000에 따라 최대 시: 0.001ms avg
avg10000에 따라 최대 시: 0.001ms avg
avg10000에 따라 최대 시: 0.001ms avg
avg10000에 따라 최대 시: 0.001ms avg
길이 문자열 생성:1950000 43ms
또한 주목할 가치가 있다.bytecode:8/java.version:13
조합은 다음에 비해 좋은 성능상의 이점이 있다.bytecode:8/java.version:8
Java 9에서 버전 1은 로 변환되기 때문에 더 빨라야 한다.invokedynamic
자세한 내용은 JEP-280을 참조하십시오.
이 아이디어는 스트링빌더 추가 댄스 전체를 java.lang.invoke에 대한 단순한 비동적 통화로 대체하자는 것이다.연결해야 하는 값을 허용하는 StringConcatFactory.
성능상의 이유로 다음 중 하나를 사용하십시오.+=
(String
결합)이 낙담하다.그 이유는: 자바String
매번 새로운 결합이 이루어질 때마다 새로운 결합이 이루어질 수 없는 것이다.String
생성됨(새 지문은 String 풀에 이미 있는 이전 지문과 다름).새로운 문자열을 만드는 것은 GC에 압력을 가하고 프로그램을 느리게 한다: 객체 생성은 비싸다.
아래 코드는 보다 실용적이고 명확해야 한다.
public static void main(String[] args)
{
// warming up
for(int i = 0; i < 100; i++)
RandomStringUtils.randomAlphanumeric(1024);
final StringBuilder appender = new StringBuilder();
for(int i = 0; i < 100; i++)
appender.append(RandomStringUtils.randomAlphanumeric(i));
// testing
for(int i = 1; i <= 10000; i*=10)
test(i);
}
public static void test(final int howMany)
{
List<String> samples = new ArrayList<>(howMany);
for(int i = 0; i < howMany; i++)
samples.add(RandomStringUtils.randomAlphabetic(128));
final StringBuilder builder = new StringBuilder();
long start = System.nanoTime();
for(String sample: samples)
builder.append(sample);
builder.toString();
long elapsed = System.nanoTime() - start;
System.out.printf("builder - %d - elapsed: %dus\n", howMany, elapsed / 1000);
String accumulator = "";
start = System.nanoTime();
for(String sample: samples)
accumulator += sample;
elapsed = System.nanoTime() - start;
System.out.printf("concatenation - %d - elapsed: %dus\n", howMany, elapsed / (int) 1e3);
start = System.nanoTime();
String newOne = null;
for(String sample: samples)
newOne = new String(sample);
elapsed = System.nanoTime() - start;
System.out.printf("creation - %d - elapsed: %dus\n\n", howMany, elapsed / 1000);
}
실행 결과는 아래에 보고되어 있다.
builder - 1 - elapsed: 132us
concatenation - 1 - elapsed: 4us
creation - 1 - elapsed: 5us
builder - 10 - elapsed: 9us
concatenation - 10 - elapsed: 26us
creation - 10 - elapsed: 5us
builder - 100 - elapsed: 77us
concatenation - 100 - elapsed: 1669us
creation - 100 - elapsed: 43us
builder - 1000 - elapsed: 511us
concatenation - 1000 - elapsed: 111504us
creation - 1000 - elapsed: 282us
builder - 10000 - elapsed: 3364us
concatenation - 10000 - elapsed: 5709793us
creation - 10000 - elapsed: 972us
1회의 연결(JIT는 아직 제 역할을 못하고 있었다) 결과를 고려하지 않은 채 10회의 연결에도 성능 벌칙은 관련이 있고 수천회의 연결에도 차이가 크다.
이 매우 빠른 실험을 통해 얻은 교훈(위의 코드로 쉽게 재현할 수 있음): 절대 사용하지 않는다.+=
몇 번의 연계가 필요한 아주 기본적인 경우라도 끈을 함께 결합하는 것(말한 바와 같이 새로운 끈을 만드는 것은 어쨌든 비용이 많이 들고 GC에 부담을 준다).
Apache Commons-Lang은 사용이 매우 쉬운 ToStringBuilder 클래스를 가지고 있다.이것은 추가 로직 처리뿐만 아니라 toString이 어떻게 보이기를 원하는지 포맷하는 것도 잘 해 준다.
public void toString() {
ToStringBuilder tsb = new ToStringBuilder(this);
tsb.append("a", a);
tsb.append("b", b)
return tsb.toString();
}
다음과 같은 출력이 반환됨com.blah.YourClass@abc1321f[a=whatever, b=foo]
.
또는 체인을 사용하여 보다 축약된 형태로:
public void toString() {
return new ToStringBuilder(this).append("a", a).append("b", b").toString();
}
또는 반사를 사용하여 클래스의 모든 필드를 포함하려는 경우:
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
원하는 경우 ToString의 스타일을 사용자 정의할 수도 있다.
StringBuilder 추가 접근법으로 가야 할 것 같아.이유:
문자열 연결은 매번 (String이 불변의 객체이므로) 새로운 문자열 객체를 생성하므로 3개의 객체를 생성한다.
String Builder를 사용하면 객체가 하나만 생성되고[StringBuilder는 변경 가능] 추가 문자열이 여기에 추가된다.
ToString 메서드를 가능한 한 읽기 쉽게 만드십시오!
내 책에 있는 이것의 유일한 예외는 그것이 상당한 자원을 소비한다는 것을 나에게 증명할 수 있느냐 하는 것이다.) (그래, 이것은 프로파일링을 의미한다)
또한 Java 5 컴파일러는 이전 버전의 Java에서 사용된 손으로 쓴 "StringBuffer" 접근법보다 더 빠른 코드를 생성한다는 점에 유의하십시오."+"를 사용하면 향후 향상된 기능은 무료로 제공되며,
현 컴파일러와 함께 스트링빌더를 사용하는 것이 여전히 필요한지에 대한 논란이 있는 것 같다.그래서 나는 내 경험 2센트를 줘야겠다고 생각했다.
나는 a를 가지고 있다.JDBC
10k 레코드 결과 세트(예, 한 묶음으로 모두 필요)+ 오퍼레이터를 사용하는 데 약 5분이 소요되며Java 1.8
. 사용stringBuilder.append("")
같은 질의에 1초도 걸리지 않는다.
그래서 차이가 크다.루프 내부StringBuilder
훨씬 빠르다.
자바8에서 확인한 내용은 다음과 같다.
- 문자열 연결 사용
StringBuilder 사용
long time1 = System.currentTimeMillis(); usingStringConcatenation(100000); System.out.println("usingStringConcatenation " + (System.currentTimeMillis() - time1) + " ms"); time1 = System.currentTimeMillis(); usingStringBuilder(100000); System.out.println("usingStringBuilder " + (System.currentTimeMillis() - time1) + " ms"); private static void usingStringBuilder(int n) { StringBuilder str = new StringBuilder(); for(int i=0;i<n;i++) str.append("myBigString"); } private static void usingStringConcatenation(int n) { String str = ""; for(int i=0;i<n;i++) str+="myBigString"; }
만약 당신이 많은 수의 끈에 끈을 연결시키는 것을 사용하고 있다면 그것은 정말 악몽이다.
usingStringConcatenation 29321 ms
usingStringBuilder 2 ms
이 이미지는 모든 수업을 비교하는 데 매우 유용할 것 같다.String
s:
만약 당신이 StringBuilder를 반복해서 사용하려고 한다면, Apache Commons Lang과 StringUtils.join()을 체크해 보는 것이 좋을 것 같다고 지적해도 될까?
성과에 상관없이, 스트링빌더와 수백만번 째로 보이는 루프를 만들어야 하는 비용을 절약할 수 있을 것이다.
문자열은 자바에서 불변하므로 '+'를 사용한 성능 지혜 문자열 연결은 스트링의 완전히 새로운 사본을 만들어야 하기 때문에 비용이 더 많이 든다.이것은 결합이 매우 빈번한 경우, 예를 들어 루프 안에서 특정한 역할을 한다.그런 일을 하려고 할 때 나의 아이디어는 다음과 같다.
일반 규칙:
- 단일 문자열 할당에서는 문자열 연결 사용으로 문제가 없다.
- 큰 문자 데이터 블록을 작성하려면 StringBuffer로 이동하십시오.
- 문자열에서 +=를 사용하는 것은 항상 StringBuffer를 사용하는 것보다 덜 효율적이기 때문에 경고 벨을 울려야 하지만, 어떤 경우에는 가독성 문제와 비교하여 얻을 수 있는 최적화는 무시할 수 있으므로, 상식을 사용하십시오.
여기 이 주제에 관한 멋진 Jon Sket 블로그가 있다.
그런 간단한 문자열은 내가 사용하는 것을 선호한다.
"string".concat("string").concat("string");
순서상, 스트링빌더 (StringBuilder), String#concat()를 사용한 다음 과부하 + 연산자를 사용하는 것이 선호된다.스트링빌더(StringBuilder)는 + 오퍼레이터를 사용하는 것과 마찬가지로 큰 문자열의 작업 시 성능이 크게 저하되는 것이다(String 크기가 증가함에 따라 현저하게 큰 감소)..concat()를 사용할 때의 한 가지 문제는 NullPointer를 던질 수 있다는 것이다.예외
'IT이야기' 카테고리의 다른 글
vuejs 구성 요소에서 생성된 후크에서 메서드 호출 (0) | 2022.05.14 |
---|---|
클립보드에 복사할 자식 구성 요소의 텍스트 영역 대상 지정 (0) | 2022.05.14 |
Android에서 내 응용 프로그램의 메모리 사용량을 검색하는 방법 (0) | 2022.05.14 |
동적 위치에 Vue 구성 요소를 삽입하는 방법 (0) | 2022.05.14 |
변수에 저장된 지정된 파일 설명자가 여전히 유효한지 확인하는 방법 (0) | 2022.05.13 |