1.String 字符串
字符串廣泛應用 在Java 編程中,在 Java 中字符串屬于對象,Java 提供了 String 類來創建和操作字符串。
創建字符串:
public class StringDemo{
public static void main(String args[]){
String str = "我是字符串"; //最簡單的創建字符串
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', 'w'};
String helloString = new String(helloArray);
System.out.println( helloString ); //hello
}
}
1.1 length() 字符串長度
用于獲取有關對象的信息的方法稱為訪問器方法。String 類的一個訪問器方法是 length() 方法,它返回字符串對象包含的字符數。
public class StringDemo{
public static void main(String args[]){
String str = "我是字符串"; //最簡單的創建字符串
System.out.println( helloString.length() ); //5
}
}
1.2 concat() 連接字符串
string1.concat(string2);
返回 string1 連接 string2 的新字符串。也可以對字符串常量使用 concat() 方法,如:
String str = "我是字符串".concat("哈哈哈哈"); //str為:我是字符串哈哈哈哈
但更常用的是使用'+'操作符來連接字符串,如:
String str = "我是字符串" + "哈哈哈哈"; //str為:我是字符串哈哈哈哈
1.3 format() 創建格式化字符串
我們知道輸出格式化數字可以使用 printf() 和 format() 方法。String 類使用靜態方法 format() 返回一個String 對象而不是 PrintStream 對象。String 類的靜態方法 format() 能用來創建可復用的格式化字符串,而不僅僅是用于一次打印輸出。
System.out.printf("浮點型變量的值為 " +
" %f, 整型變量的值為 " +
" %d, 字符串變量的值為 " +
" %s", floatVar, intVar, stringVar);
String fs;
fs = String.format("浮點型變量的值為 " +
" %f, 整型變量的值為 " +
" %d, 字符串變量的值為 " +
" %s", floatVar, intVar, stringVar);
2.StringBuffer 和 StringBuilder 類
當對字符串進行修改的時候,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,并且不產生新的未使用對象。
StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)。
由于 StringBuilder 相較于 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程序要求線程安全的情況下,則必須使用 StringBuffer 類。
public class Test{
public static void main(String args[]){
StringBuffer sBuffer = new StringBuffer("百度:");
sBuffer.append("www");
sBuffer.append(".baidu");
sBuffer.append(".com");
System.out.println(sBuffer); //百度:www.baidu.com
}
}
2.1 StringBuffer 類支持的主要方法
public StringBuffer append(String s)
將指定的字符串追加到此字符序列。
public StringBuffer reverse()
將此字符序列用其反轉形式取代。
public delete(int start, int end)
移除此序列的子字符串中的字符。
public insert(int offset, int i)
將 int 參數的字符串表示形式插入此序列中。
replace(int start, int end, String str)
使用給定 String 中的字符替換此序列的子字符串中的字符。
3.String方法
3.1 charAt()
charAt()方法用于返回指定索引處的字符。索引范圍為從 0 到 length() - 1
public class Test {
public static void main(String args[]) {
String s = "http:www.baidu.com";
System.out.println(s.charAt(5)); //w
}
}
3.2 compareTo() 和 compareToIgnoreCase()
compareTo()方法用于比較兩個字符串:str1.compareTo(str2)
compareToIgnoreCase()和compareTo()一樣,只是在比較時不考慮字母大小寫
返回值是整型,它是先比較對應字符的大小(ASCII碼順序),如果第一個字符和參數的第一個字符不等,結束比較,返回他們之間的差值,如果第一個字符和參數的第一個字符相等,則以第二個字符和參數的第二個字符做比較,以此類推,直到字符出現不同就計算這兩個不同字符的ASCII碼的差,作為返回值,若到最后某一個字符串結束了,此時返回的是兩個字符串的長度差。
如果str1與str2相等,返回0
如果str1大于str2,返回一個大于0的整數
如果str1小于str2,返回一個小于0的整數
public class Test {
public static void main(String args[]) {
String str1 = "Strings";
String str2 = "Strings";
String str3 = "Strings123";
System.out.println(str1.compareTo( str2 )); //0
System.out.println(str2.compareTo( str3 )); //-3
System.out.println(str3.compareTo( str1 )); //3
String str4 = "abcde";
String str5 = "abdde";
System.out.println(str5.compareTo( str4 )) //-1 此時返回的才是ASCII差值
}
}
3.3 contentEquals()
contentEquals()方法用于將此字符串與指定的 StringBuffer 比較。如字符串與指定 StringBuffer 表示相同的字符序列,則返回 true;否則返回 false。
public class Test {
public static void main(String args[]) {
String str1 = "String1";
String str2 = "String2";
StringBuffer str3 = new StringBuffer( "String1");
System.out.println(str1.contentEquals( str3 ));//true
System.out.println(str2.contentEquals( str3 ));//false
}
}
3.4 equals() 和 equalsIgnoreCase()
equals()方法用于將字符串與指定的對象比較。如果給定對象與字符串相等,則返回 true;否則返回 false。
equalsIgnoreCase() 與 equals() 作用一樣,只是比較時忽略大小寫
public class Test {
public static void main(String args[]) {
String Str1 = new String("hello");
String Str2 = Str1;
String Str3 = new String("hello");
System.out.println(Str1.equals( Str2 )); //true
System.out.println(Str1.equals( Str3 )); //true
}
}
3.5 copyValueOf()
copyValueOf()方法有兩種形式:
public static String copyValueOf(char[] data): 返回指定數組中表示該字符序列的字符串。
public static String copyValueOf(char[] data, int offset, int count): 返回指定數組中表示該字符序列的 字符串。
public class Test {
public static void main(String args[]) {
char[] Str1 = {'h', 'e', 'l', 'l', 'o', ' ', 'r', 'u', 'n', 'o', 'o', 'b'};
System.out.println(String.copyValueOf( Str1 ));//hello runoob
System.out.println(String.copyValueOf( Str1, 2, 6 ));//llo ru
}
}
3.6 startsWith() 和 endsWith()
startsWith()用于檢測字符串是否以指定的前綴開始。
endsWith()用于測試字符串是否以指定的后綴結束。如果參數表示的字符序列是此對象表示的字符序列的后綴,則返回 true;否則返回 false。注意,如果參數是空字符串,或者等于此 String 對象(用 equals(Object) 方法確定),則結果為 true。
public class Test {
public static void main(String args[]) {
String Str = new String("https://www.baidu.com");
System.out.println(Str.startsWith( "https" )); //true
System.out.println(Str.startsWith( "www" )); //false
System.out.println(Str.startsWith( "www",8 )); //true
System.out.println(Str.endsWith( "baidu" )); //false
System.out.println(Str.endsWith( "com" ));//true
}
}
3.7 getBytes()
getBytes()方法有兩種形式:
getBytes(String charsetName): 使用指定的字符集將字符串編碼為 byte 序列,并將結果存儲到一個新的 byte 數組中。
getBytes(): 使用平臺的默認字符集將字符串編碼為 byte 序列,并將結果存儲到一個新的 byte 數組中。
import java.io.*;
public class Test {
public static void main(String args[]) {
String Str1 = new String("runoob");
try{
byte[] Str2 = Str1.getBytes();
System.out.println( Str2 );//[B@7852e922
Str2 = Str1.getBytes( "UTF-8" );
System.out.println(Str2 );//[B@4e25154f
Str2 = Str1.getBytes( "ISO-8859-1" );
System.out.println(Str2 );//
} catch ( UnsupportedEncodingException e){
System.out.println("不支持的字符集");//[B@70dea4e
}
}
}
3.8 getChars()
getChars()方法將字符從字符串復制到目標字符數組。
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
srcBegin:字符串中要復制的第一個字符的索引。
srcEnd:字符串中要復制的最后一個字符之后的索引。
dst:目標數組。
dstBegin:目標數組中的起始偏移量。
沒有返回值,但會拋出 IndexOutOfBoundsException 異常。
public class Test {
public static void main(String args[]) {
String Str1 = new String("www.baidu.com");
char[] Str2 = new char[5];
try {
Str1.getChars(4, 9, Str2, 0);
System.out.println(Str2 ); //baidu
} catch( Exception ex) {
System.out.println("觸發異常...");
}
}
}
3.9 hashCode()
hashCode()方法用于返回字符串的哈希碼。
字符串對象的哈希碼根據以下公式計算:s[0]31^(n-1) + s[1]31^(n-2) + ... + s[n-1](使用 int 算法,這里 s[i] 是字符串的第 i 個字符,n 是字符串的長度,^ 表示求冪??兆址墓V禐?0。)
public class Test {
public static void main(String args[]) {
String Str = new String("www.runoob.com");
System.out.println( Str.hashCode() );//321005537
}
}
3.10 indexOf()
indexOf()方法有以下四種形式:
public int indexOf(int ch): 返回指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public int indexOf(int ch, int fromIndex): 返回從 fromIndex 位置開始查找指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
int indexOf(String str): 返回指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
int indexOf(String str, int fromIndex): 返回從 fromIndex 位置開始查找指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public class Main {
public static void main(String args[]) {
String string = "aaa456ac";
//查找指定字符是在字符串中的下標。在則返回所在字符串下標;不在則返回-1.
System.out.println(string.indexOf("b")); // indexOf(String str); 返回結果:-1,"b"不存在
// 從第四個字符位置開始往后繼續查找,包含當前位置
System.out.println(string.indexOf("a",3));//indexOf(String str, int fromIndex); 返回結果:6
//(與之前的差別:上面的參數是 String 類型,下面的參數是 int 類型)參考數據:a-97,b-98,c-99
// 從頭開始查找是否存在指定的字符
System.out.println(string.indexOf(99));//indexOf(int ch);返回結果:7
System.out.println(string.indexOf('c'));//indexOf(int ch);返回結果:7
//從fromIndex查找ch,這個是字符型變量,不是字符串。字符a對應的數字就是97。
System.out.println(string.indexOf(97,3));//indexOf(int ch, int fromIndex); 返回結果:6
System.out.println(string.indexOf('a',3));//indexOf(int ch, int fromIndex); 返回結果:6
}
}
3.11 lastIndexOf()
lastIndexOf()方法有以下四種形式:
public int lastIndexOf(int ch): 返回指定字符在此字符串中最后一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public int lastIndexOf(int ch, int fromIndex): 返回指定字符在此字符串中最后一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public int lastIndexOf(String str): 返回指定字符在此字符串中最后一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public int lastIndexOf(String str, int fromIndex): 返回指定字符在此字符串中最后一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
public class Test {
public static void main(String args[]) {
String Str = new String("www.baidu.com");
String SubStr1 = new String("baidu");
String SubStr2 = new String("com");
System.out.print("查找字符 o 最后出現的位置 :" );
System.out.println(Str.lastIndexOf( 'o' ));
System.out.print("從第10個位置查找字符 o 最后出現的位置 :" );
System.out.println(Str.lastIndexOf( 'o', 10 ));
System.out.print("子字符串 SubStr1 最后出現的位置:" );
System.out.println( Str.lastIndexOf( SubStr1 ));
System.out.print("從5個位置開始搜索子字符串 SubStr1最后出現的位置 :" );
System.out.println( Str.lastIndexOf( SubStr1, 5 ));
System.out.print("子字符串 SubStr2 最后出現的位置 :" );
System.out.println(Str.lastIndexOf( SubStr2 ));
}
}
3.12 intern()
intern()方法返回字符串對象的規范化表示形式。
它遵循以下規則:對于任意兩個字符串 s 和 t,當且僅當 s.equals(t) 為 true 時,s.intern() == t.intern() 才為 true。
public class Test {
public static void main(String args[]) {
String Str1 = new String("www.baidu.com");
String Str2 = new String("WWW.BAIDU.COM");
System.out.println(Str1.intern()); //www.baidu.com
System.out.println(Str2.intern()); //WWW.BAIDU.COM
}
}
盡管在輸出中調用intern方法并沒有什么效果,但是實際上后臺這個方法會做一系列的動作和操作。在調用"ab".intern()方法的時候會返回"ab",但是這個方法會首先檢查字符串池中是否有"ab"這個字符串,如果存在則返回這個字符串的引用,否則就將這個字符串添加到字符串池中,然會返回這個字符串的引用。
可以看下面一個范例:
String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
String str5 = new String("ab");
System.out.println(str5.equals(str3));
System.out.println(str5 == str3);
System.out.println(str5.intern() == str3);
System.out.println(str5.intern() == str4);
得到的結果:
true
false
true
false
第一、str5.equals(str3)這個結果為true,不用太多的解釋,因為字符串的值的內容相同。
第二、str5 == str3對比的是引用的地址是否相同,由于str5采用new String方式定義的,所以地址引用一定不相等。所以結果為false。
第三、當str5調用intern的時候,會檢查字符串池中是否含有該字符串。由于之前定義的str3已經進入字符串池中,所以會得到相同的引用。
第四,當str4 = str1 + str2后,str4的值也為”ab”,但是為什么這個結果會是false呢?先看下面代碼:
String a = new String("ab");
String b = new String("ab");
String c = "ab";
String d = "a" + "b";
String e = "b";
String f = "a" + e;
System.out.println(b.intern() == a);
System.out.println(b.intern() == c);
System.out.println(b.intern() == d);
System.out.println(b.intern() == f);
System.out.println(b.intern() == a.intern());
運行結果:
false
true
true
false
true
由運行結果可以看出來,b.intern() == a和b.intern() == c可知,采用new 創建的字符串對象不進入字符串池,并且通過b.intern() == d和b.intern() == f可知,字符串相加的時候,都是靜態字符串的結果會添加到字符串池,如果其中含有變量(如f中的e)則不會進入字符串池中。但是字符串一旦進入字符串池中,就會先查找池中有無此對象。如果有此對象,則讓對象引用指向此對象。如果無此對象,則先創建此對象,再讓對象引用指向此對象。
當研究到這個地方的時候,突然想起來經常遇到的一個比較經典的Java問題,就是對比equal和 == 的區別,當時記得老師只是說“==”判斷的是“地址”,但是并沒說清楚什么時候會有地址相等的情況。現在看來,在定義變量的時候賦值,如果賦值的是靜態的字符串,就會執行進入字符串池的操作,如果池中含有該字符串,則返回引用。
3.13 length()
length() 方法用于返回字符串的長度。
public class Test {
public static void main(String args[]) {
String Str1 = new String("www.baidu.com");
String Str2 = new String("baidu" );
System.out.println(Str1.length()); //13
System.out.println(Str2.length()); //5
}
}
3.14 matches()
matches()方法用于檢測字符串是否匹配給定的正則表達式
public class Test {
public static void main(String args[]) {
String str = new String("www.baidu.com");
System.out.println(str.matches("(.*)baidu(.*)")); //true
System.out.println(str.matches("(.*)google(.*)")); //false
System.out.println(str.matches("www(.*)")); //true
}
}
3.15 regionMatches()
regionMatches()方法用于檢測兩個字符串在一個區域內是否相等.語法:
public boolean regionMatches(int toffset,
String other,
int ooffset,
int len)
或
public boolean regionMatches(boolean ignoreCase,
int toffset,
String other,
int ooffset,
int len)
參數說明:
ignoreCase -- 如果為 true,則比較字符時忽略大小寫。
toffset -- 此字符串中子區域的起始偏移量。
other -- 字符串參數。
ooffset -- 字符串參數中子區域的起始偏移量。
len -- 要比較的字符數。
public class Test {
public static void main(String args[]) {
String Str1 = new String("www.baidu.com");
String Str2 = new String("baidu");
String Str3 = new String("BAIDU");
System.out.println(Str1.regionMatches(4, Str2, 0, 5)); //true
System.out.println(Str1.regionMatches(4, Str3, 0, 5)); //false
System.out.println(Str1.regionMatches(true, 4, Str3, 0, 5));//true
}
}
3.16 replace()
replace()通過用 newChar 字符替換字符串中出現的所有 oldChar 字符,并返回替換后的新字符串
public String replace(char oldChar, char newChar)
public class Test {
public static void main(String args[]) {
String Str = new String("hello");
System.out.println(Str.replace('o', 'l')); //helll
System.out.println(Str.replace('l', 'L')); //heLLo
}
}
3.17 replaceAll() 和 replaceFirst()
replaceAll()方法使用給定的參數 replacement 替換字符串所有匹配給定的正則表達式的子字符串。替換后生成的新字符串。
replaceFirst()方法使用給定的參數 replacement 替換字符串第一個匹配給定的正則表達式的子字符串。成功則返回替換的字符串,失敗則返回原始字符串。
public String replaceAll(String regex, String replacement)
public String replaceFirst(String regex,String replacement)
public class Test {
public static void main(String args[]) {
String str1 = new String("www.baidu.com");
System.out.println(str1.replaceAll("(.*)baidu(.*)", "google" ));//google
System.out.println(str1.replaceAll("(.*)taobao(.*)", "google" ));//www.baidu.com
String str2 = new String("hello baidu,I am from baidu。");
System.out.println(str2.replaceFirst("baidu", "google" )); //hello google,I am from baidu
System.out.println(str2.replaceFirst("(.*)baidu(.*)", "google" )); //google
}
}
3.18 split()
split()根據匹配給定的正則表達式來拆分字符串。
注意:
. 、 | 和 * 等轉義字符,必須加 \\
多個分隔符,可以用 | 作為連字符
public String[] split(String regex, int limit) //返回字符串數組
regex:正則表達式分隔符。
limit:分割的份數。
public class Test {
public static void main(String args[]) {
String str = new String("nice-to-meet-you");
String retval1 = str.split("-"); //["nice","to","meet","you"]
String retval12 = str.split("-",2); //["nice","to-meet-you"]
String str2 = new String("www.baidu.com");
String retval3 = str2.split("\\.", 3) //["www","baidu","com"]
String str3 = new String("acount=? and uu =? or n=?");
String retval4 = str3.split("and|or") //["acount=? "," uu =? "," n=?"]
}
}
3.19 subSequence() 和 substring()
subSequence()返回一個新的字符序列,它是此序列的一個子序列
substring()返回字符串的子字符串。
public CharSequence subSequence(int beginIndex, int endIndex)
public class Test {
public static void main(String args[]) {
String str = new String("www.baidu.com");
System.out.println(str.subSequence(4, 5) ); //baidu
System.out.println(str.substring(4) ); //baidu.com
System.out.println(str.substring(4, 9) ); //baidu
}
}
3.20 toCharArray()
toCharArray()將字符串轉換為字符數組。
public class Test {
public static void main(String args[]) {
String str = new String("www.baidu.com");
System.out.println( str.toCharArray() ); //www.baidu.com
}
}
3.21 toLowerCase() 和 toUpperCase()
toLowerCase()使用默認語言環境的規則將此 String 中的所有字符都轉換為小寫。
toUpperCase()使用默認語言環境的規則將此 String 中的所有字符都轉換為大寫。
public class Test {
public static void main(String args[]) {
String str = new String("WWW.BAIDU.COM");
String str1 = new String("www.baidu.com");
System.out.println( str.toLowerCase() ); //www.baidu.com
System.out.println( str1.toUpperCase() ); //WWW.BAIDU.COM
}
}
3.22 toString()
toString()返回此對象本身(它已經是一個字符串)。
public class Test {
public static void main(String args[]) {
String str = new String("www.baidu.com");
System.out.println( str.toString() ); //www.baidu.com
}
}
3.23 trim()
trim()用于刪除字符串的頭尾空白符。
public class Test {
public static void main(String args[]) {
String str = new String(" www.baidu.com ");
System.out.println( str.trim() ); //www.baidu.com
}
}
3.24 基礎面試題
第一題:
說說length() 方法,length 屬性和 size() 方法的區別?
答:
1、length() 方法是針對字符串來說的,要求一個字符串的長度就要用到它的length()方法;
2、length 屬性是針對 Java 中的數組來說的,要求數組的長度可以用其 length 屬性;
3、Java 中的 size() 方法是針對泛型集合說的, 如果想看這個泛型有多少個元素, 就調用此方法來查看!
第二題:
為什么說String 類是不可改變的?
String s = "Google";
System.out.println(s); //Google
s = "Baidu";
System.out.println(s); //Baidu
原因在于實例中的 s 只是一個 String 對象的引用,并不是對象本身,當執行 s = "Baidu"; 創建了一個新的對象 "Baidu",而原來的 "Google" 還存在于內存中。