一、String類是什麼 由第一段源碼可知,String是一個final類,底層實現是final的字元數組,一旦創建,無法改變。 字元串是常量;他們的值在創建之後不能改變。字元串緩衝區支持可變的字元串。因為String對象是不可變的,所以可以共用。 二、如何創建 String s1 = "abc"; ...
一、String類是什麼
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L;
由第一段源碼可知,String是一個final類,底層實現是final的字元數組,一旦創建,無法改變。
字元串是常量;他們的值在創建之後不能改變。字元串緩衝區支持可變的字元串。因為String對象是不可變的,所以可以共用。
二、如何創建
String s1 = "abc";//字元串常量池中創建一次(如不存在)
String s2 = new String("abc");//字元串常量池中和堆中各創建一次
// 更多的構造器,請參見API
關於一個比較經典的面試題:String s1 = new String("hello");創建了幾個對象的問題,可以參考源碼中相關的構造器的源碼,結合String的記憶體分析,便可以從深入進行理解了!
關於這個問題,詳見:http://www.cnblogs.com/dangzhenjiuhao/p/4585389.html
三、常用方法
第一部分:基本都是見名知意,詳細的介紹,請參見API
代碼示例:
@Test public void test1() { String str = "HelloWorld"; // length()——字元串的長度 System.out.println(str.length());// 10 // charAt(int)——指定索引處(索引從0開始)的char System.out.println(str.charAt(2));// 1 // equals(Object)——比較字元串的內容;equalsIgnoreCase不區分大小寫的比較 System.out.println("HelloWorld".equals(str));// true // indexOf()——索引操作(包含幾個重載方法);lastIndexOf()為鏡像操作,不再贅述 System.out.println(str.indexOf(2)); // -1(不存在2的字元) System.out.println(str.indexOf("llo")); // 2 // startsWith()——是否以指定字元串開頭;endsWith()——為鏡像操作 System.out.println(str.startsWith("ello", 1));// true // regionMatches()——與指定字元串的區域匹配,包含兩個重載方法,詳細介紹參見API System.out.println(str.regionMatches(2, "hello", 2, 2));// true }
第二部分
代碼實例:
@Test public void test2() { String str = "more love"; // subString()——字元串截取,兩個重載方法都是左閉的(兩個參數的右開) System.out.println(str.substring(5, 8));// lov // replace()——進行替換操作;replaceAll是匹配正則表達式的,詳細請參見API System.out.println(str.replace('o', 'e'));// mere leve // trim()——去除前導空白和尾部空白 System.out.println(str.trim());// mere leve // concat()——連接字元串 System.out.println(str.concat(" for you")); // more love for you // split()——根據正則表達式分割字元串,拆分為String[] System.out.println("a,b,c,d,e".split(",").length);// 5 }
以下幾個練習題可以試試!
// 1.如何實現自己的trim // 通過charAt進行遍歷,從頭開始遍歷到到非空格,再從尾部做一遍,subString()取值即可(註意異常情況) // 2.反轉字元串中的指定的部分 // 將字元串分割成3份,一份前面的,一份需要反轉的,一份後面的,再將第2部分反轉,添加,再組合成新的字元串 // 3.獲取一個字元串在另外一個字元串中出現的次數 // 通過indexOf(String)的迴圈判斷,不斷向後判斷,直到末尾 // 4.找出兩個字元串中最大相同子串 // 將短的串依次遞減(第一位減掉,比較;最後一位減掉,比較,整數前兩位減掉,迴圈...)看長串是否包含
String類與基本數據類型的轉換:
@Test public void test3() { String str = "123"; // String轉基本數據類型,通過包裝類的parse系列方法 int i = Integer.parseInt(str); // 基本數據類型轉String,簡單的可以直接+"",通過方法是String.valueOF(),或者toString() String s = String.valueOf(i); // String與位元組數組的轉換:str.getBytes()方法得到位元組數組;再通過String構造器將位元組數組轉為字元串 byte[] bytes = str.getBytes(); String s1 = new String(bytes); //String與字元數組的轉換:str.toCharArray()方法,char[]轉String同樣是可以通過構造器 char[] chars = str.toCharArray(); String s2 = new String(chars); }
四、可變字元串StringBuffer與StringBuilder
其中,StringBuffer是線程安全的,而StringBuilder是線程不安全的,但它效率更高
基本構造器:
StringBuffer sb = new StringBuffer(); StringBuffer sb2 = new StringBuffer("abc");
// 當然它的底層還是字元數組,但它有容量的概念,修改的時候是可以改變容量的
常用的方法:
@Test public void test4() { StringBuffer sb = new StringBuffer("abc"); // append()——追加 System.out.println(sb.append("def").toString());//"abcdef" // insert()——在指定位置插入 System.out.println(sb.insert(1, "bb"));//abbbcdef // reverse()——反轉 System.out.println(sb.reverse().toString());//fedcbbba // 其它和字元串相類似的方法不再贅述 }
,