spring - string

dkpp發表於2024-03-06

spring - string

1.string

在 Java 8 及之前的版本中,字串由不可變的 Unicode 字元陣列組成。然而,大多數字符只需要 8 位(1 個位元組)來表示它們,而不是 16 位(字元大小)。
為了改善記憶體消耗和效能,Java 9 引入了緊湊字串。這意味著如果字串僅包含 1 位元組字元,它將使用Latin-1編碼表示。如果字串至少包含 1 個多位元組字元,則使用 UTF-16 編碼將其表示為每個字元 2 個位元組。
在 C 和 C++ 中,String也是一個字元陣列,但在 Java 中,它是一個具有自己的 API 的單獨物件。

2.字串不可變有什麼好處

根據James Gosling 的採訪,字串是不可變的,以提高效能和安全性。
實際上,我們看到了使用不可變字串的幾個好處:
2.1僅當字串一旦建立就永遠不會更改時,字串池才是可能的,因為它們應該被重用
2.2該程式碼可以安全地將字串傳遞給另一個方法,因為知道該方法無法更改它
2.3不可變地自動使此類成為執行緒安全的
2.4由於該類是執行緒安全的,因此 不需要同步公共資料,從而提高了效能
2.5由於保證它們不會改變,因此可以輕鬆快取它們的雜湊碼

3.字串如何儲存在記憶體中

根據 JVM 規範,字串文字儲存在 執行時常量池中,該常量池是從 JVM 的方法區分配的。
儘管方法區在邏輯上是堆記憶體的一部分,但規範並未規定位置、記憶體大小或垃圾收集策略。它可以是特定於實現的。
類或介面的執行時常量池是在 JVM 建立類或介面時構造的。

4.什麼是字串常量池

字串池,也稱為 字串常量池或 字串實習池,是 JVM 儲存String例項的特殊記憶體區域。
它透過減少分配字串的頻率和數量來最佳化應用程式效能:
JVM在池中僅儲存特定字串的一份副本
當建立一個新的String時,JVM 在池中搜尋具有相同值的String
如果找到,JVM 將返回對該字串的引用,而不分配任何額外的記憶體
如果沒有找到,那麼 JVM 將其新增到池中(實習它)並返回其引用

5.字串是執行緒安全的嗎

字串確實是完全執行緒安全的,因為它們是不可變的。任何不可變的類都會自動符合執行緒安全性,因為它的不可變性保證了其例項不會在多個執行緒中更改。
例如,如果執行緒更改字串的值,則會建立一個新 字串 ,而不是修改現有字串。

6.我們如何在 Java 中比較兩個字串?str1 == str2和str1.equals(str2)之間有什麼區別?

運算子 ( str1 == str2 ) 檢查引用相等性
方法 ( s​​tr1.equals(str2) ) 檢查詞法相等

7. 什麼是 Stringjoiner

StringJoiner 是 Java 8 中引入的一個類,用於將單獨的字串連線成一個,例如獲取顏色列表並將它們作為逗號分隔的字串返回。我們可以提供分隔符以及字首和字尾:

StringJoiner joiner = new StringJoiner(",", "[", "]");
joiner.add("Red")
  .add("Green")
  .add("Blue");

assertEquals("[Red,Green,Blue]", joiner.toString());

8.String、Stringbuffer 和 Stringbuilder 之間的區別?

字串是不可變的。這意味著如果我們嘗試更改或改變它的值,那麼 Java 會建立一個絕對新的String。
例如,如果我們在建立字串str1 後新增它:

String str1 = "abc";
str1 = str1 + "def";

然後 JVM 不會修改str1,而是建立一個全新的String。
然而,對於大多數簡單的情況,編譯器內部使用StringBuilder並最佳化上述程式碼。
但是,對於更復雜的程式碼(例如迴圈),它將建立一個全新的String,從而降低效能。這就是StringBuilder和StringBuffer有用的地方。
Java 中的StringBuilder和StringBuffer都建立儲存可變字元序列的物件。StringBuffer 是同步的,因此是執行緒安全的,而StringBuilder不是。
由於StringBuffer 中的額外同步 通常是不必要的,因此我們通常可以透過選擇 StringBuilder 來提高效能 。

9.String 的 intern() 方法有什麼作用?

intern()方法 在堆中 建立String物件 的精確副本 ,並將其儲存在JVM 維護的String 常量池中。
Java 會自動駐留所有使用字串文字建立的字串,但如果我們使用 new 運算子建立 String ,例如String str = new String(“abc”),那麼 Java 會將其新增到堆中,就像任何其他物件一樣。
我們可以呼叫 intern()方法來告訴 JVM 將其新增到字串池(如果字串池中尚不存在),並返回該 interned 字串的引用:

String s1 = "Baeldung";
String s2 = new String("Baeldung");
String s3 = new String("Baeldung").intern();

assertThat(s1 == s2).isFalse();
assertThat(s1 == s3).isTrue();

10.常見方法

char[] hello = "hello".toCharArray();
assertArrayEquals(new String[] { 'h', 'e', 'l', 'l', 'o' }, hello);

byte[] byteArray2 = "efgh".getBytes(StandardCharsets.US_ASCII);
byte[] byteArray3 = "ijkl".getBytes("UTF-8");

long count = "hello".chars().filter(ch -> (char)ch == 'l').count();
assertEquals(2, count);

String reversed = new StringBuilder("baeldung").reverse().toString();
assertEquals("gnudleab", reversed);

相關文章