Java基礎之二_字串
一 字串建立、判斷相等/為空
1.1 建立字串:雙引號與new
引號和new建立的區別:https://www.cnblogs.com/wdfordream/p/9449710.html
字串物件的建立很特殊,除了像一般物件那樣通過new建立物件外,還能用雙引號直接為字串引用變數指定字串物件的值。其實,考慮到字面值常量的概念,雙引號的字串內容其實也可以理解為一個引用(變數),只不過這個引用(變數)的名稱和其指向的物件代表的值一樣。如例子所示,雙引號字串可以像引用變數一樣直接呼叫字串類的方法,可見其確實是一個引用(變數)
System.out.println("abc".length()); // 3
引號建立,意味著在是在程式中寫死的,在程式執行之前其對應的字串物件就是確定的了。引號建立的字串物件就是常量,會在程式載入時建立(猜的),而且被存放到JVM維護的字串例項池。
new建立,則字串物件是在程式執行時建立的,和普通物件一樣,儲存在堆中。
引號建立時,JVM會先在字串例項池中是否已存在,如果已存在直接返回地址,不重複建立,所以多次建立實際為同一個物件。new建立時,總是會在堆中開闢新的記憶體區域,多次建立為不同物件。引號建立和new建立的字串物件所在的記憶體區域都不同,二者自然不是同一個物件。
連結中部落格說:new建立字串物件時,也會先在字串例項池中查詢,如果沒有,也會同時在字串例項池中建立。那麼下面這種情況也是嗎?
String str1 = "abc";
String str2 = str1.substring(0,1);
System.out.println(str2);
str2也會在字串例項池中建立嗎?
總結:
在Java中與字串相關的記憶體區域有三個:字串例項池、堆、棧。程式碼中用雙引號寫明的字串物件都存放在字串例項池,new建立的字串物件放在堆,字串物件的引用放在棧。
補充:
Java字面值常量:https://blog.csdn.net/qq_36756682/article/details/102664502
- 考慮到字面值常量概念,那字串物件存在的兩種建立方式、判斷值相等得用equals等問題其實也不算特殊。因為所有內建型別都存在字面值常量,所以其他內建物件也存在一樣的問題,如下面例子所示。
- 之所以對其他內建型別感覺沒這麼明顯,是因為:從理解上看,String對標的應該是Integer、Character這些物件;但在操作上,Java中為這些內建資料型別提供了其他關鍵字,如:int、char,所以Integer、Character就用的少了,問題就不突出了。但是字串對應的只有String一個關鍵字。【int型別其實比String更復雜,具體見下面例子】
- 判斷Integer物件的值是否相等使用的依然是equals(),可見equals相當重要。equals可是從Object中繼承的方法。
- 字面值常量:1、2、‘a’、‘b’…儲存在哪?常量池,具體參考以下博文:
https://blog.csdn.net/mrdmmm/article/details/89484474
https://blog.csdn.net/chenkaibsw/article/details/80848069
Integer i = new Integer(1);
Integer i1 = 1;
Character ch = new Character('a');
Character ch1 = 'a';
String str = new String("abc");
String str1 = "abc";
System.out.println(i==i1); // false
System.out.println(ch==ch1); // false
System.out.println(str==str1); // false
System.out.println(i.equals(i1)); // true
System.out.println(ch.equals(ch1)); // true
System.out.println(str.equals(str1)); // true
再補充一個int的例子,這才叫跌破眼鏡:
Integer i = new Integer(1);
Integer j = 1;
int k =1;
System.out.println(i==j); // false
System.out.println(i==k); // true
System.out.println(j==k); // true
1. 注意看,i和j不等,這在上面已經分析過了;但是二者竟然都能和k相等;注意看,是物件相等。
2. 換句話說:k==i、k==j,推不出i==j,怎麼解釋?
3. 個人理解這是操作符過載,==操作符在涉及int、char...時,不再表示物件相等,而是表示值相等。
4. 可見基本資料型別int、char等真是極其特殊,只用考慮值,不做物件考慮。
5. int i=1 和 int j=3-2,是等價的,沒有區別,Integer i=1 和 Integer j=3-2,也是等價的,是同一個物件
1.2 字串物件判斷相等/為空:
字串判斷相等/為空這種說法本身是不明確的,應該說判斷:字串物件值相等、字串物件相等、字串物件值為空、字串物件為空。
等號運算子"==",用於判斷物件相等,即同一塊記憶體單元。equals()方法,用於判斷物件的值相等,所有類都存在equals方法(繼承自Object)。
判斷字串物件相等:==
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); // true
判斷字串物件值相等:equals
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1.equals(str2)); // true
判斷字串物件為空:== null
【注意null物件也能進行== 運算】
String str1 = null;
System.out.println(str1==null); // true
判斷字串物件值為空: equals("")、length()==0
【確定字串物件不為null的情況下才能按以下寫法】
String str1 = "";
System.out.println(str1.equals(""));
System.out.println(str1.length()==0);
【不確定是否為null,更穩妥的寫法如下:】
String str1 = "";
System.out.println("".equals(str1)); // true
System.out.println(str1!==null && str1.length()==0); // true
綜上所述:
1.與字串物件本身相關的判斷,都用==,且只能用==
2.與字串物件值相關的判斷,都用equals(),判斷值為空也可以使用length()
補充:
什麼叫物件為空?什麼叫物件沒有初始化?有什麼區別?
- 物件為空並不是說物件沒有值,而是說物件為空值,也即物件的值為null。這個null值,可以是手動賦的,也可以是第三方函式的返回結果,也可能是靜態變數由JVM預設初始化的。
- 物件沒有初始化說的是物件沒有值,區域性變數定義後沒有賦初值就會出現這個問題。
- 呼叫沒有初始化的物件是編譯時問題,在IDE中就會報紅;呼叫為空值的物件是執行時的問題,程式執行時才會報錯。【空指標異常】
二 字串常量和字串變數
字串變數變數的說法是錯誤的,應該叫字串緩衝變數,為了好記,將錯就錯
2.1 String、StringBuffer、StringBuilder的區別
https://blog.csdn.net/csxypr/article/details/92378336
https://blog.csdn.net/fzy198926/article/details/88792365
- String變數不應該叫字串物件,而應該叫字串物件的引用變數。實際上,建立任意物件時,都不應該把XXX叫做XXX物件,而應該叫做XXX物件的引用變數。物件存放在堆,引用變數存放在棧。
- 字串物件(不是指引用變數)是一個常量,一旦建立值就不能改變,也就是所對應的記憶體單元的值不能改變,長時間不使用,會被垃圾回收;
- 對字串物件的各種改變實際上是建立了新的字串物件,分配了新的記憶體單元,並讓原來的引用變數指向這個新的字串物件。
根據上面的敘述,顯而易見,程式中要頻繁修改字串物件的值時,使用字串物件是很不利的。此時,應該使用字串緩衝物件StringBuffer、StringBuilder,這兩個(指向的物件)是可變的,不會產生新的物件,可在修改完成後再轉為String物件。【不僅比String佔記憶體小,執行的也更快】
StringBuffer和StringBuilder的區別在於:
二者方法和功能完全是等價的,區別在於:StringBuffer是執行緒安全的,有同步機制;StringBuilder不是執行緒安全的,但因此更快。單執行緒時優先使用StringBuilder,多執行緒時使用StringBuffer。
2.2 StringBuffer、StringBuilder
https://www.runoob.com/java/java-stringbuffer.html
二者API一致,且訪問物件的操作與String物件也類似,主要是使用修改操作,包括:append、insert、delete、replace、reverse。
StringBuilder stringBuilder = new StringBuilder("123");
stringBuilder.append("456"); // 123456
stringBuilder.insert(0,"abc"); // abc123456
stringBuilder.delete(0,2); // c123456
stringBuilder.replace(0,1,"xyz"); // xyz123456
stringBuilder.reverse(); // 654321zyx
System.out.println(stringBuilder.toString());
注意:
String類沒有reverse方法,StringBuilder才有。在字串表示大數時,可能涉及reverse操作,因為數值高位在左邊,而陣列高位在右邊。
三 字串常用操作
3.1 字串與字元陣列轉換
String s = "123";
char[] chars = s.toCharArray();
String str = String.valueOf(chars);
注意:
若用字串表示數值,在轉為字元陣列時要特別注意,數值高位在陣列低位
3.2 字串擷取
四 正規表示式
相關文章
- Java基礎系列—字串Java字串
- mybatis基礎之二MyBatis
- java基礎之二:取整函式(Math類)Java函式
- 字串基礎字串
- JVM 內部原理(七)— Java 位元組碼基礎之二JVMJava
- Django基礎之二(URL路由)Django路由
- Java基礎-處理json字串解析案例JavaJSON字串
- JavaSE基礎:字串Java字串
- Python基礎知識之二Python
- 檔案管理基礎命令之二
- Git詳解之二:Git基礎Git
- Java基礎之字串String詳細解釋Java字串
- java基礎:String — 字串常量池與intern(二)Java字串
- Python基礎—字串Python字串
- oracle spatial之基礎知識之二Oracle
- 基礎知識修改字串字串
- Python基礎(02):字串Python字串
- Go基礎-字串函式Go字串函式
- [Python基礎]字串操作Python字串
- python基礎之字串Python字串
- 零基礎學Java第四節(字串相關類)Java字串
- JAVA基礎學習-數字與字串學習總結Java字串
- Golang 基礎值速學之二十(go mod)Golang
- windows批處理之二:基礎知識Windows
- Oracle之PL/SQL基礎學習之二OracleSQL
- Java基礎-語法基礎Java
- JAVA 基礎Java
- 【Java基礎】Java
- java基礎Java
- [Java基礎]Java
- 【重溫基礎】8.字串字串
- Shell基礎教程七:Shell字串字串
- C#字串基礎學習C#字串
- Groovy基礎語法-字串篇字串
- Java 基礎02Java程式設計基礎Java程式設計
- java基礎-java NIOJava
- Java基礎-物件導向基礎Java物件
- android基礎學習-java篇day7-step3-第三節:java字串AndroidJava字串