Java 개발자들 사이에서는 문자열 스플라이싱의 높은 리소스 소모가 종종 화제가 됩니다.
왜 높은 리소스를 차지하는지 심층적으로 논의해 보겠습니다.
Java에서 문자열객체는 불변입니다. 즉, 일단 생성되면 변경할 수 없습니다. 따라서 문자열을 연결하면 새 문자열이 생성되고 이전 문자열은 가비지 수집기에 의해 표시됩니다.
수백만 개의 문자열을 처리하면 가비지 수집기에서 처리할 수백만 개의 추가 문자열이 생성됩니다.
가상머신의 하위 레이어에서는 문자열을 연결할 때 많은 작업을 수행합니다. 문자열을 연결하는 가장 직접적인 도트 연산자는 String#concat(String) 작업입니다.
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }
public static char[] copyOf(char[] original, int newLength) { char[] copy = new char[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); }
문자 배열이 생성된 것을 볼 수 있는데, 길이는 기존 문자와 연결 문자의 길이를 합한 값이다. 그런 다음 해당 값이 새 문자 배열에 복사됩니다. 마지막으로 이 문자 배열에서 String 객체를 생성하고 반환합니다.
그래서 이러한 연산이 많아 계산해 보면 복잡도가 O(n^2)라는 것을 알 수 있습니다.
이 문제를 해결하기 위해 StringBuilder 클래스를 사용합니다. 이는 변경 가능한 String 클래스와 같습니다. 접합 방법은 불필요한 중복을 방지하는 데 도움이 됩니다. 이는 O(n^2)보다 훨씬 더 나은 O(n)의 복잡성을 갖습니다.
그러나 Java 8은 기본적으로 StringBuilder를 사용하여 문자열을 연결합니다.
Java 8에 대한 설명서에서는 :
문자열 연결 성능을 향상시키기 위해 Java 컴파일러에서 StringBuffer 클래스 또는 유사한 기술을 사용할 수 있다고 명시합니다. 값 표현식 일 때 중간 String 객체 생성을 줄입니다.
Java 컴파일러는 이 상황을 처리합니다.
public class StringConcatenateDemo { public static void main(String[] args) { String str = "Hello "; str += "world"; } }
위 코드는 다음 바이트코드로 컴파일됩니다.
public class StringConcatenateDemo { public StringConcatenateDemo(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: ldc #2 // String Hello 2: astore_1 3: new #3 // class java/lang/StringBuilder 6: dup 7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 10: aload_1 11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: ldc #6 // String world 16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_1 23: return }
다음 바이트코드를 사용할 수 있습니다. StringBuilder가 사용됩니다. 따라서 Java 8에서는 더 이상 StringBuilder 클래스를 사용할 필요가 없습니다.
위 내용은 Java 8에서 문자열을 연결하는 데 더 이상 필요하지 않은 StringBuilder에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!