Java Grammar:幾道面試題學習String

科技伍小黑 發佈 2020-01-29T15:12:55+00:00

下面我們通過幾道面試題來學習String類如何創建一個字符串一般來說有三種:通過new關鍵字通過構造方法去創建通過雙引號「」通過字符串連接符+和其餘字符串進行拼接創建說說這幾種的區別當通過new關鍵字調用無參構造時,僅僅在JVM的堆內存中創建了一個對象通過""創建對象的時候,如果

幾道面試題學習String

字符串介紹

String類是java.lang包中的一個類,是我們日常中使用的非常多的一個類,它不是基礎數據類型,底層實現是字符數組來實現的:

/** The value is used for character storage. */
    private final char value[];

String類是由final修飾的,所以是無法被繼承的,一旦創建了String對象,我們就無法改變它的值。因此,它是線程安全的,可以安全地用於多線程環境中。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence

下面我們通過幾道面試題來學習String類

如何創建一個字符串

一般來說有三種:

  • 通過new關鍵字通過構造方法去創建
  • 通過雙引號「」
  • 通過字符串連接符+和其餘字符串進行拼接創建

說說這幾種的區別

  1. 當通過new關鍵字調用無參構造時,僅僅在JVM的堆內存中創建了一個對象
  2. 通過""創建對象的時候,如果字符串常量池存在該字符串,直接返回該字符串對象在字符串常量池的地址,否則創建一個新的字符串對象並存儲在字符串常量池。

String s = new String(「a」) 創建了幾個對象

當通過new關鍵字傳入雙引號字符串參數時,會先去把該雙引號的字符串放入字符串常量池,然後遇到new以後會在堆中再次創建一個字符串對象,這裡是創建了兩個對象。



+ 的實現原理

String s1 = null;
String s2 = "abc";
System.out.println(s1 + s2);

借這道面試題來聊一下+的原理,這道題的答案是」nullabc「,也許會有些奇怪,但是當你了解了+的原理後也許就不會感到奇怪了,我們使用javap命令去看一下編譯器那裡把+編譯成了什麼?



我們在圖中被紅色框柱的部分可以看出,+的執行的過程其實就是先把 String轉換成了StringBuilder後調用append方法完成拼接後再調用toString方法完成字符串的拼接。所以上面的代碼也可以轉換為

StringBuilder s1 = new StringBuilder(String.valueOf(null));
StringBuilder s2 = new StringBuilder("abc");
s1.append(s2).toString();

關於StringBuilder和StringBuffer

StringBuffer 和 StringBuilder 二者都繼承了 AbstractStringBuilder ,底層都是利用可修改的char數組(JDK 9 以後是 byte數組)。兩者的區別是StringBuilder是線程不安全的,而StringBuffer是線程安全的。性能上來說,StringBuilder要高於StringBuffer。

在單線程情況下,如有大量的字符串操作情況,不能使用String來拼接而是使用,避免產生大量無用的中間對象,耗費空間且執行效率低下(新建對象、回收對象花費大量時間)。這時就需要用到我們的StringBuilder。

而在多線程情況下,應當使用StringBuffer來保證線程的安全~

判空

在日常的開發中,我們經常會遇到判斷字符串是否為空的需求,這裡安利幾個工具類中的寫法:

// 來自apache下的lang3包中的StringUtils
import org.apache.commons.lang3.StringUtils
....
  
  
  //這裡是判斷是否為null或為空
  String s;
  StringUtils.isNotEmpty(s);

        //這裡是用於判斷是否為null或為空,或空格,Tab這樣的占用符
        StringUtils.isNotBlank(s);

是否相等

關於兩個字符串是否相等,我用的最多的是java.util包下的Objects類中的方法 ,實現方法如下:

public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
}

用法也很簡單:

Objects.equals(a,b);

關鍵字: