<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                >[success] # 字符串總結 1. `String s = "abc";` 這種直接賦值字符串常量的情況,**此時字符串abc是存在字符串常量池中的**,整個創建過程**先檢查字符串常量池中有沒有字符串abc,如果有,不會創建新的,而是直接復用。如果沒有abc,才會創建一個新的。** 2. 通過 `new` 關鍵字幾種形式創建字符串,一定是在堆里面開辟了一個空間,`new`出來的,在**堆里面的地址** 3. 字符串的比較推薦使用`equals` 方法,因為在 `java` 中`==`號比較 * 如果比較的是**基本數據類型**:比的是具體的數值是否相等 * 如果比較的是**引用數據類型**:比的是地址值是否相等 在 `java` 中 String 是**引用類型**,在使用雙等時候比較其實是內存地址,因此要注意的是比較內容使用提供的`equals` 方法 4. 關于字符串的拼接**加號浪費性能** * 如果拼接的全部都為字符串,在拼接時候會觸發字符串的優化機制,**在編譯轉換為class 文件后就已經獲取了最終值的結果** ![](https://img.kancloud.cn/31/19/3119ad9bbce8aea59113c19440c12034_897x184.png) ~~~ public class StringTest { public static void main(String[] args) { String str = "a" + "b" + "c"; // 實際在編譯后class 就是"abc" } } ~~~ * 如果拼接是變量在**JDK8以前**:系統底層會自動創建一個`StringBuilder`對象,然后再調用其`append`方法完成拼接。拼接后,再調用其`toString`方法轉換為`String`類型,而`toString`方法的底層是直接`new String`了一個字符串對象(可看源碼實現)。也就是說**一個加號使用變量拼接字符串會創建兩個對象**分別是`StringBuilder` 和 `String` ![](https://img.kancloud.cn/d9/62/d9622b3f7dc783028cf5f32a1fdc2668_1528x649.png) ~~~ public class StringTest { public static void main(String[] args) { String s1 = "a"; String s2 = "b" + s1; // 實際做了 new StringBuilder().append(s1).append("b").toString(); } } ~~~ * **JDK8版本**:系統會預估要字符串拼接之后的總大小,把要拼接的內容都放在數組中,此時也是產生一個新的字符串。(?????) ***** * 加號浪費性能案例說明method1 > method2 ,結論**字符串拼接的時候有變量參與:在內存中創建了很多對象浪費空間,時間也非常慢不要直接使用加號創建** ~~~ public static void main(String[] args) { int times = 1_0000; long startTime = System.currentTimeMillis(); method1(times); System.out.println("method1 耗時:" + (System.currentTimeMillis() - startTime)); startTime = System.currentTimeMillis(); method2(times); System.out.println("method2 耗時:" + (System.currentTimeMillis() - startTime)); } public static void method1(int times) { String s = ""; for (int i = 0; i < times; i++) { s += i; } } public static void method2(int times) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(i); } String s = sb.toString(); } ~~~ 5. 在字符串的拼接時候更多應該使用`StringBuilder` 這種內容可變的容器,創建后只有一個對象在內存空間 6. [參考鏈接](https://www.jianshu.com/p/dc8a458d5933),`StringBuilder`這種擴容也是存在一定規則的(**容量和長度的區別,容量表示最多能裝多少,長度表示實際內容**) * 默認創建一個長度為16的字節數組 * 添加的內容長度小于16,直接存 * 添加的內容大于16會擴容(原來的容量*2+2) * 如果擴容之后還不夠,以實際長度為準 ~~~ public class StringTest { public static void main(String[] args) { StringBuilder sb1 = new StringBuilder(); sb1.append("abc"); System.out.println(sb1.capacity()); // 容量 16 System.out.println(sb1.length()); // 長度 3 // 添加內容大于目前的容量。那么會進行擴容公式 原始容量*2 + 2 sb1.append("defghijklmnopqrstvuwxzy"); System.out.println(sb1.capacity()); // 容量 16*2 +2 = 34 System.out.println(sb1.length()); // 長度 26 // 如果添加內容大于 實際擴容長度應該為16*2 +2 = 34,但添加的內容遠遠大于34 因此 // 擴容和長度值相等 StringBuilder sb2 = new StringBuilder(); sb2.append("111111111111111111111111111111111111"); System.out.println(sb2.capacity()); // 容量 36 System.out.println(sb2.length()); // 長度 36 } } ~~~ * 如果你默認有構造參數初始容量為**16 + 字符串長度** ~~~ public class StringTest { public static void main(String[] args) { StringBuilder sb1 = new StringBuilder("abc"); sb1.append("abc"); System.out.println(sb1.capacity()); // 容量 19 System.out.println(sb1.length()); // 長度 6 } } ~~~ >[danger] ##### 面試題 * 因為 s3 在拼接后實際是產生新對象在堆中,但`s1` 實際在字符串常量池中,因此比較后地址值不同 ~~~ public class StringTest { public static void main(String[] args) { String s1 = "abc"; String s2 = "ab"; String s3 = s2 + "c"; System.out.println(s1 == s3); // false } } ~~~ * s2 轉換為class 文件后實際 "abc",s1 已經在常量池中創建了,因此s2直接復用即可,所以內存地址指向相同 ~~~ public class StringTest { public static void main(String[] args) { String s1 = "abc"; String s2 = "a" + "b" + "c"; // 轉換為class 文件后實際 "abc" System.out.println(s1 == s2); // true } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看