字符串 - java中的String

關於String的一些實用技能

一、String

面試經常會看到關於String,到底String是怎麼一回事呢 ?

  • String的常量池
    JVM在堆中開闢了一段空間迎來緩存所有使用字面量
    創建的字符串對象,只要發現已經創建過的字符串
    字面量創建新字符串時,JVM會直接使用緩存的對象
    而不是在創建新對象,這樣做避免內存堆積大量
    內容一樣的字符串對象,降低內存開銷
   一、
        //直接量 字面量
		String s1 = "123abc";
		String s2 = "123abc";//重用S1創建的對象
		String s3 = "123abc";//一樣重用

		System.out.println(s1==s2);//true
		System.out.println(s1==s3);//true

上邊爲什麼會是true?
s1、s2、s3 三個裏面內容是相同的;s3會利用之前(s1)的緩存123abc 。( s2同理 )
所以爲true。

   二、	        
        String s1 = "123abc";
		String s2 = "123abc";
		//一旦修改內容,就會創建新對象
		s1 = s1+"!";//s1不在指向原對象
		System.out.println("s1:"+s1);//123abc!
		System.out.println("s2:"+s2);//123abc

這個時候s1輸出爲 123abc!,會不在指向原對象。

   三、
		String s2 = "123abc";
		//new是一個比較強制的操作,一定創建新對象
		String s4 = new String("123abc");
		System.out.println("s4:"+s4);
		System.out.println(s2==s4);//false

這次會輸出false,因爲new是一個比較強制的操作,一定創建個對象。
雖然內容相同,但是兩者對象不同,所以比較爲false!

   四、
        /**
         * 這裏觸發了編譯器一個特點
         * 編譯器在編譯代碼時若出現一個表達式
         * 參與的值都是字面量時,那麼該計算表達式的結果
         * 是確定的,此時編譯器計算表達式的結果,將結果替換表達式
         * 這樣一來JVM每次執行字節碼文件就不用計算了
         * 下面的代碼會被編譯器編譯後爲:
         * String s5="123abc";
         */
	   String s5 = "123"+"abc";
	   String s2 = "123abc";
	   System.out.println("s5:"+s5);
	   System.out.println(s2==s5);//true

上邊說到了,編譯器的特點。雖然兩者是相加的,但表達式參與值爲字面量,直接把結果確定;
兩者對象比較,值相同,所以爲false

  五、
	   String s = "123";
	   String s6 = s+"abc";
	   System.out.println(s2==s6);//false

上邊說到了,當使用了字面量時,會自動變爲結果進行比較。
當使用了一個變量,不是字面量時。進行比較對象,爲false!

二、String不適合頻繁修改

     字符串是不變對象,若想改變內容一定會創建新對象
     這樣的做法源自JVM對字符串的優化,但是這樣的做法
     弊端修改字符串時性能低下(雖然這樣的操作不頻繁)
     頻繁修改產生大量垃圾,內存開銷大,運行效率差

結論:String不適合頻繁修改

三、String、StringBuffer、StringBuilder區別

StringBuffer與StringBuilder相同點都是字符串變量,是可改變的對象,每當我們用它們對字符串做操作時,
實際上是在一個對象上操作的。String每次操作會創建一些新的對象,所以速度快些。

不同點是StringBuilder是線程非安全的,StringBuffer是線程安全的, 當我們在字符串緩衝區被多個線程使用時,
JVM不能保證StringBuilder的操作是安全的,雖然它的速度最快,但是可以保證StringBuffer是可以正確操作的。
當然大多數情況下我們是在單線程下進行的操作,所以大多數情況下建議使用StringBuilder而不用StringBuffer的,
就是速度的原因。

對於三者使用的總結:
1.如果要操作少量的數據使用 String。
2.單線程操作字符串緩衝區,操作大量數據使用 StringBuilder。     
3.多線程操作字符串緩衝區,操作大量數據使用 StringBuffer。

--------------------------------------------------------

String的使用

1、 char charAt(int index)

  • 下標 獲取當前字符串中指定位置對應的字符

    String str="thinking in java";
    char c=str.charAt(9);
    System.out.println(c);//i
    

注意:第一個是從0開始數的。
這時會輸出String str變量中的第九個下標對應的。

2、int indexOf(String str)

  • 檢定給定的當前字符串中的位置

  • 若當前字符串不包含給定內容,則返回值爲-1

       String str="thinking in java";
       //查找str中"in"所在的位置
       int index = str.indexOf("in");//2
       
       System.out.println(index);
       //從指定位置開始查找第一次出現"in"的位置
       index = str.indexOf("in",3);
       System.out.println(index);//5
       
       //查找最後一次出現"in"位置
       index = str.lastIndexOf("in");
       System.out.println(index);//9
    

3、int length()

  • 獲取當前字符串長度(字符個數)

      String str = "我愛java!!";
      int length = str.length();
      System.out.println("len:"+length);//len:8
    

4、boolean startsEith(String str)

boolean endsWith(String str)

  • 判斷一個字符串是否以字符開始或結尾的

     String str="thinking in java";
     
     boolean starts =str.startsWith("thi");
     System.out.println("start:"+starts);//true
     
     boolean ends =str.endsWith("ava");
     System.out.println("ends:"+ends);//true
    

5、String substring(int start,int end)

  • 截取指定範圍內的字符串,兩個參數分別表示下標

  • 從start處開始,end結束(不包含end處的字符)

  • java API中的參數有一個特點,通常用兩個數字表示

  • 範圍時都是“含頭不含尾”的。

      String str="eee.hhhh.com";
      
      String sub=str.substring(4,8);
      System.out.println(sub);//hhhh
      
      //從指定位置開始截取到字符串末尾
      sub=str.substring(4);
      System.out.println(sub);//hhhh.com
    

6、String toUpperCase()

String toLowerCase()

  • 將當前英文字符部分轉換爲全大寫或全小寫

      String str="我愛java,LALALA";
     String upper =str.toUpperCase();
     System.out.println(upper);//我愛JAVA,LALALA
    
     String lower=str.toLowerCase();
     System.out.println(lower);//我愛java,lalala
    

7、String trim()

  • 去除字符串兩邊的空白字符

     String str="   				h e l l o		";
     System.out.println(str); //  				h e l l o		
    
    
     String trim=str.trim();                                             
     System.out.println(trim);//hello
    
     System.out.println(str.trim());//hello
    

這兩個結果都是相同的,只是用法不一樣。

8、static String valueOf(XXX xxx)

  • 字符串提供了一組靜態的重載的valueOf方法,作用

  • 是將其他類型轉換爲字符串

     int a=123;
     String s1=String.valueOf(a);
     System.out.println(s1);//123
    
     double d=123.123;
     String s2=String.valueOf(d);
     System.out.println(s2);//123.123
    
     String s3=a+"";
     System.out.println(s3);//123
    

補充StringBuffer的使用

    String str="努力學習java";

	StringBuilder b=new StringBuilder(str);
	System.out.println(b);

	/**
	 * 增
	 * append():將給定內容拼接到字符串末尾
	 */
	b.append(",爲了找個好工作!");
	
	//獲取StringBuilder內部表示的字符串
	str = b.toString();
	System.out.println(str);

	/**
	 * 改
	 * 怒力學習java,爲了找個好工作!
	 * 怒力學習java,就是爲了改變世界!
	 */
	b.replace(9,17,"爲了改變世界!");
	System.out.println(b);

	/**
	 * 刪
	 */
	b.delete(0,9);
	System.out.println(b);

	/**
	 * 插:
	 */
	b.insert(0, "活着,就是");
	System.out.println(b);

StringBuilder修改字符串性能

    StringBuilder builder = new StringBuilder("a");
	for(int i=0;i<100000000;i++){
		builder.append("a");
	}
	System.out.println("執行完畢!");

這樣是在同一個變量改變,所以效率比較高,
StringBuufer是安全的,StringBuilder是不安全的。

---------------------------------------------------

String和正則表達式配合使用

關於正則表達式

大小寫不同,意思也就不同

\w    [a-zA-Z0-9_]  單詞字符
\W    非單詞字符
\d    [0-9]      任意一個數字
\D    非數字
\s    空白
\S    非空白

1、 String支持正則表達式的方法一:

  • boolean matches(String regex)
  • 使用給定的正則表達式驗證當前字符串是否符合格式

簡單判斷是否符合郵箱格式

       //String email = "[email protected]";
    	  String email="myweb/reg?username=xxx&password=xxx&....";
    	  String regex="\\?";
		/*
		 * \w+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+;
		 * 使用字符串描述正則表達式
		 */   
		//String regex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)";
		boolean match=regex.equals(email);
		if(match){
			System.out.println("是郵箱");
		}else {
			System.out.println("不是郵箱");
		}

2、 String 支持正則表達式方法二:

  • String[] split(string regex)
  • 將當前字符串按照滿足正則表達式的部分進行拆分,
  • 將拆分後的部分以數組形式返回

拆分小例子

       String line = "abc123bcd456efg789hji";
		/*
		 * 按照數字部分拆分,得到所有的字母部分
		 */
		//String []arr1=line.split("[0-9]+");
		
		/**
		 * 如果在拆分中出現了可連接的可拆分項 時,他們中間會拆分一個空字符串。
		 * 如果字符串開始就是拆分項時,前面也會拆分出 一個空字符串
		 * 注意:如果是字符串末尾連續匹配拆分項,那麼所有拆分出的空串全部忽略
		 */
		String []arr=line.split("[0-9]");
		System.out.println(arr.length);
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
		String image ="123.png";
		String []date=image.split("\\.");
		image =date[1];
		System.out.println(image);

3、 String 支持正則表達式三:

  • String replaceALL(String regex ,String str)
  • 將當前字符串中滿足正則表達式部分替換爲給定內容

替換小例子

        String str1 = "abc123def456ghi789jkl";
		/*
		 * 將數字部分替換爲"#NUMBER#"
		 */
		String str = str1.replaceAll("[0-9]+","#NUMBER#");
		System.out.println(str);

4、和諧用語

當使用不文明語句,可以判斷是否符合條件,然後進行替換,
例子如下:

    String regex = "(dsb|mdzz|cnm|wqnmlgb)";
	String message = "wqnmlgb!cnm";
	message = message.replaceAll(regex,"**");
	System.out.println(message);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章