Java——String類(總結的也是超級詳細了)
一、String類-Java.long.String
1.1 String類的兩種例項化方式
a . 直接賦值,在堆上分配空間。
String str = "hello";
b . 傳統方法。通過構造方法例項化String類物件
String str1 = new String("Hello");
1.2字串相等比較
採用String類提供的equals方法。
public boolean equals(String anotherString):成員方法 str1.equals(anotherString); eg: public class Demo2{ public static void main(String[] args){ String str1 = "hello"; String str2 = "hello"; System.out.println(str1==str2); } } 執行結果:true eg: public class Demo2{ public static void main(String[] args){ String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1==str2); } } 執行結果:false eg: public class Demo2{ public static void main(String[] args){ String str1 = "hello"; String str2 = new String("hello"); System.out.println(str1.equals(str2)); } } 執行結果:true
面試題:請解釋String 類和==的區別:
- ”==”:進行的數值比較,比較的是兩個字串物件的記憶體地址數值。
- “equals()”:可以進行字串內容的比較
1.3 字串常量(“ “)是String的匿名物件。
public class Demo2{ public static void main(String[] args){ String str1 = "hello"; System.out.println("hello".equals(str1)); } } 如果能夠執行成功,說明字串“hello”是String的匿名物件 執行結果:true
小tips:以後開發中,如果要判斷使用者輸入的字串是否等同於特定字串,一定要將特定字串(String常量)寫在前面,避免空指標異常(NullPointerException)。
System.out.println(str1.equals(“hello”)); 錯誤
System.out.println(“hello”.equals(str1)); 正確
1.4 字串共享問題:
JVM底層會自動維護一個字串的物件池(物件陣列),如果現在採用直接賦值的形式進行String的物件例項化,該物件會自動儲存在這個物件池中。如果下次繼續使用直接賦值的模式宣告String物件,此時物件池中若有指定內容,則直接引用;如果沒有,則開闢新的堆空間後將其儲存在物件池中供下次使用。
public class Demo2{
public static void main(String[] args){
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
System.out.println(str1==str2);
System.out.println(str2==str3);
System.out.println(str1==str3);
}
}
執行結果:
true
true
true
public class Demo2{
public static void main(String[] args){
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1==str2);
}
}
new新開闢了空間
執行結果:false
手工入池(本地方法):
public native String intern();
eg:
public class Demo2{
public static void main(String[] args){
String str1 = "hello";
String str2 = new String("hello").intern();
System.out.println(str1==str2);
}
}
執行結果:true
面試題:請解釋String類中兩種物件例項化的區別
- 直接賦值:只會開闢一塊堆記憶體空間,並且該字串物件可以自動儲存在物件池中以供下次使用。
- 構造方法:會開闢兩塊堆記憶體空間,其中一塊成為垃圾空間,不會自動儲存在物件池中,可以使用intern()方法手工入池。
因此,我們一般會採取第一種方式即直接賦值。
1.5 字串常量不可變更
字串一旦定義後不可變。
public class Demo2{
public static void main(String[] args){
String str1 = "hello";
str1 += " world";
str1 += "!!!";
System.out.println(str1);
}
}
執行結果:hello world!!!
其實字串沒有變化,是字串的引用一直在改變,而且會形成大量的垃圾空間。
原則:
- 字串使用就採用直接賦值。
- 字串比較就使用equals()實現。
- 字串別改變太多。(字串”+“操作,不超過三次)。
1.6 字元與字串的相互轉換
a.將字元陣列轉為字串 -> String
--public String(char[] value) //將陣列中的全部字元轉換成字串
eg:
public class Demo2{
public static void main(String[] args){
char[] data = new char[]{'h','e','l','l','o'};
String str = new String(data);
System.out.println(str);
}
}
執行結果:hello
--public String(char[] value,int offset,int count) //將陣列中的部分字元轉換成字串
eg:
public class Demo2{
public static void main(String[] args){
char[] data = new char[]{'h','e','l','l','o'};
String str = new String(data,2,3);
System.out.println(str);
}
}
執行結果:llo
b.將字串轉為單個字元
public char charAt(int index):
eg:
public class Demo2{
public static void main(String[] args){
char c = "hello".charAt(4);
System.out.println(c);
}
}
執行結果:o
c.將字串變為字元陣列:String -> char[]
--public char[] tocharArray();
eg:
public class Demo2{
public static void main(String[] args){
char[] c = "hello".toCharArray();
System.out.println(c);
System.out.println("hello".length()); //字串是方法
System.out.println(c.length); //陣列是屬性
}
}
執行結果:
hello
5
5
取得字串長度:public int length();
//判斷一個字串是否由數字組成
public class Demo2{
public static void main(String[] args){
System.out.println(isNumber("123"));
}
public static boolean isNumber(String str){
char[] data = str.toCharArray();
for(int i=0;i<data.length;i++){
if(data[i]<'0' || data[i]>'9'){
return false;
}
}
return true;
}
}
執行結果:
true
1.7 位元組(Byte)與字串
a.將位元組陣列轉換為字串(重點)
byte[] ->String
public String(byte[] value)
eg:
public class Demo2{
public static void main(String[] args){
byte[] data = new byte[]{1,2,3,4,5};
String str = new String(data);
System.out.println(str);
}
}
執行結果:
╔╗╚╝║
public String(byte[] value,int offset,int count)//將位元組陣列的指定位元組轉換成字串
b.將字串轉為位元組陣列 (重點)
String->byte[]
public byte[] getBytes();
eg:
public class Demo2{
public static void main(String[] args){
String str = "hello";
byte[] data = str.getBytes();
for(byte b:data){
System.out.print(b+"、");
}
}
}
執行結果:
104、101、108、108、111、
c.將字串按指定編碼轉為位元組陣列
public byte[] getBytes(String charsetName);
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str = "你好世界";
byte[] data = str.getBytes("gbk");
for(byte b: data){
System.out.print(b+"、");
}
System.out.print(new String(data));
}
}
(根據編碼的不同,結果也相應不同)
執行結果:
-60、-29、-70、-61、-54、-64、-67、-25、你好世界
1.8 字串比較
a.不區分大小寫相等比較
public boolean equalsIgnoreCase(String anotherString)
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str = "hello";
System.out.println("Hello".equalsIgnoreCase(str));
}
}
執行結果:true
b. 比較兩個字串大小
public int compareTo(String anotherString)
I.返回大於0:表示大於比較物件
II.返回等於0:兩者相等
III.返回小於0:表示小於比較物件
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "Hello";
String str2 = "hellO";
System.out.println(str1.compareTo(str2));
}
}
只要遇到第一個不同的進行比較。
執行結果:
-32
【支援中文】
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "張";
String str2 = "李";
System.out.println(str1.compareTo(str2));
}
}
執行結果:
-2094
1.9 字串查詢(重點)
- 判斷str在本字串中是否存在
public boolean contains(String str) :判斷str在本字串中是否存在
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "he";
String str2 = "hello";
System.out.println(str2.contains(str1));
}
}
執行結果:true
- 判斷是否以指定字串開頭
public boolean startsWith(String str) : 判斷是否以指定字串開頭
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "he";
String str2 = "hello";
System.out.println(str2.startsWith(str1));
}
}
執行結果:true
- 從指定位置判斷是否以指定字串開頭
public boolean startsWith(String str,int index) : 從指定位置判斷是否以指定字串開頭
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "ll";
String str2 = "hello";
System.out.println(str2.startsWith(str1,2));
}
}
執行結果:true
- 判斷是否以指定字串結尾
public boolean endsWith(String str) : 判斷是否以指定字串結尾
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "lo";
String str2 = "hello";
System.out.println(str2.endsWith(str1));
}
}
執行結果:true
1.10字串替換
public String replaceAll(String regex,String replacement) :替換所有指定內容
public String replaceFirst(String regex,String replacement) :替換首個內容
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str = "hello world";
System.out.println(str.replaceAll("l","-"));//替換所有指定內容
System.out.println(str.replaceFirst("l","-"));//替換首個內容
}
}
執行結果:he--o wor-d
執行結果:he-lo world
1.11字串拆分
——public String[] split(String regex) :將字串按照指定格式全部拆分
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "hello world hello java";
String[] result = str1.split(" ");
for(String str:result){
System.out.println(str);
}
}
}
執行結果:
hello
world
hello
java
——public String[] split(String regex,int limit) : 將字串部分拆分,陣列長度為limit
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "hello world hello java";
String[] result = str1.split(" ",2);
for(String str:result){
System.out.println(str);
}
}
}
執行結果:
hello
world hello java
//拆分地址
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "196.168.1.1";
String[] result = str1.split("\\."); //注意這裡有轉義字元
for(String str:result){
System.out.println(str);
}
}
}
執行結果:
196
168
1
1
1.12字串擷取(常用)
public String substring(int beginIndex):[ 從指定位置擷取到字串的結尾
public String substring(int beginIndex,int endIndex):[) 擷取部分內容
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "helloworld";
String result1 = str1.substring(3);//從指定位置擷取到字串的結尾
String result2 = str1.substring(3,6);//擷取部分內容
System.out.println(result1);
System.out.println(result2);
}
}
執行結果:
loworld
low
1.13 String 類其他方法
a.去掉左右空格
public String trim();
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = " hello world ";
String result = str1.trim();
System.out.print(result);
}
}
執行結果:
hello world
b.轉大小寫
public String toUpperCase(); //小寫轉大寫
public String toLowerCase(); //大寫轉小寫
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "hello world";
String str2 = "HELLO WORLD";
String result1 = str1.toUpperCase();
System.out.println(result1);
System.out.println(str2.toLowerCase());
}
}
執行結果:
HELLO WORLD
hello world
String類並沒有提供首字母大寫操作,需要自己實現。
public class Demo2{
public static void main(String[] args) throws Exception{
String str = "hello";
System.out.print(firstCase(str));
}
public static String firstCase(String str){
return str.substring(0,1).toUpperCase() + str.substring(1);
}
}
執行結果:
Hello
c.判斷字串是否為空(只能判斷是否為空字串,而不是null;
public boolean isEmpty();
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
String str1 = "";
String str2 = "haha";
System.out.println(str1.isEmpty());
System.out.println(str2.isEmpty());
}
}
執行結果:
true
false
if(str == null || str.isEmpty()) //完整的空字串的方法
1.14兩隻sb(面試題)—方便進行字串的修改
StringBuffer
StringBuilder
a.字串修改
public StringBuffer append(各種資料型別)
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer();
sb.append("hello").append("world").append(10);
System.out.println(sb);
}
}
執行結果:
helloworld10
b.StringBuffer <->String
I.String -> StringBuffer
呼叫StringBuffer的構造方法或append()
II.StringBuffer.toString();
StringBuffer.toString();
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer("hello");
String result = sb.toString();
System.out.println(result.isEmpty());
}
}
執行結果:
false
c.字串反轉
public StringBuffer reverse();
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer("helloworld");
sb.reverse();
System.out.println(sb);
}
}
執行結果:
dlrowolleh
【支援中文】
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer("你好");
sb.reverse();
System.out.println(sb);
}
}
執行結果:
好你
d.刪除指定範圍的資料
public StringBuffer delete(int start,int end);
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer("hello world");
sb.delete(0,4);
System.out.println(sb);
}
}
執行結果:
o world
e.插入資料
public StringBuffer insert(int offset,各種資料型別)
eg:
public class Demo2{
public static void main(String[] args) throws Exception{
StringBuffer sb = new StringBuffer("hello world");;
System.out.println(sb.insert(5,"(你好)"));
}
}
執行結果:
hello(你好) world
I.string的內容不可修改,而兩隻sb可以修改內容(append)
II.StringBuffer 採用同步處理,執行緒安全,效率較低。
StringBuilder採用非同步處理,執行緒不安全,效率較高,String"+"底層會將String -> StringBulider