javaSE三個特殊的類 -- String類&String類面試題
String類
String類
-
String的兩種例項化方式
直接賦值(用的最多)
String str=“Hello”;
傳統方法,例項化物件
String str=new String("Hello");
-
字串相等比較
str.equals(str1); //比較的是內容
public boolean equals(String str1)
-
字串常量是String類的匿名物件
tips:在指定內容比較時,將指定內容(字串常量)寫在前面,避免NullPointException
面試題:請解釋String類“==”與“equals”的區別
-
“==”:進行的是數值比較,比較的是兩個字串物件的記憶體地址數值
-
“equals()”:可以進行字串內容的比較
-
String採用共享設計模式 在JVM底層自動維護一個字串物件池(物件陣列)。
如果採用直接賦值的模式進行String類的物件例項化操作,此物件將自動儲存到物件池中,如果有,直接引用,如果沒有,開闢新的空間將其儲存到物件池中共下次使用;
物件池就是一個物件陣列目的就是減少記憶體的開銷
字串手工入池操作:
public native String intern();
範例:
- // 該字串常量並沒有儲存在物件池之中
- String str1 = new String("hello");
- String str2 = "hello" ;
- System.out.println(str1 == str2); // false
- ----------------------------------
- ----------------------------------
- // 使用手動入池操作
- String str1 = new String("hello").intern() ;
- String str2 = "hello" ;
- System.out.println(str1 == str2); // true
面試題:請解釋String類中兩種物件例項化的區別
-
直接賦值 就會自動採用共享模式,只會開闢一塊堆記憶體空間,並且該字串物件可以自動儲存在物件池中以供下次使用。
-
構造方法 就會開闢兩塊堆記憶體空間並且其中一塊堆記憶體將成為垃圾空間,不會自動儲存在物件池中,可以使用intern()方法手工入池。
-
字串常量不可變更
字串常量一旦定義不可改變
範例:觀察如下程式碼
- String str = "hello" ;
- str = str + " world" ;
- str += "!!!" ;
- System.out.println(str); // hello world!!!
以上字串變更是字串物件變更而非字串常量
記憶體中的字串修改如下圖所示:
可以發現字串上沒有發生變化,但是字串物件的引用一直在改變,並且形成了大量垃圾空間。正是因為 String的特點,所以如下程式碼不應該在你的開發中出現:
- String str = "hello" ;
- for(int x = 0 ; x<1000 ; x++) {
- str += x ;
- }
- System.out.println(str)
如果有很多使用者都使用了同樣的操作,那麼產生的垃圾數量就相當可觀了。
字串使用原則
-
字串使用就採用直接賦值
-
字串比較就使用equals()實現
-
字串不要改變太多,防止產生過多垃圾空間
-
字元與字串 String <-> char[]
1. 字元陣列 char[]-> String
功能:將字元陣列中所有內容變為字串
建構函式為:public String ( char[] value1 ) ;
功能:將部分字元陣列中的內容變為字串
建構函式為:public String ( char[] value1, int offset, int count ) ;
2. String -> char
功能:將字串按照索引轉為單個字元
普通函式:public char charAt ( int index ) ;
如果使用charAt()方法超出了字串長度,則會產生StringIndexOutOfBoundsException異常
3. String -> char[] *** 重點 ***
功能:將字串轉為字元陣列
普通函式:public char[] toCharArray( ) ;
範例:
- public class Test{
- public static void main(String[] args){
- String str = "helloworld" ;
- // 將字串變為字元陣列
- char[] data = str.toCharArray() ;
- for (int i = 0; i < data.length; i++) {
- data[i] -= 32 ;
- System.out.print(data[i]+"、");
- }
- // 字元陣列轉為字串
- System.out.println(new String(data)); // 全部轉換
- System.out.println(new String(data,5,5)); // 部分轉換
- }
- }
- //輸出
- //H、E、L、L、O、W、O、R、L、D、HELLOWORLD
- //WORLD
面試題:判斷給定字串是否由數字組成? *** 重要 ***
- public class Test{
- public static void main (String[] args){
- String str="123";
- boolean a=MyAdjust(str);
- if(a==true){
- System.out.println("字串是由數字組成!");
- }
- else{
- System.out.println("字串中含有非數字成員!");
- }
- }
- public static boolean MyAdjust(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;
- }
- }
-
位元組與字串
功能:位元組陣列轉為字串 byte[] -> String
String構造方法:public String(byte[] bytes)
功能:字串轉為位元組陣列 String -> byte[] *** 非常重要 ***
String普通方法:public byte[] getBytes(String charset);按照指定編碼轉為位元組陣列
亂碼的產生(編解碼不一致,順序不一致)
範例:
- public class Test {
- public static void main(String[] args) {
- String str = "helloword";
- byte[] data = str.getBytes();
- for (int i = 0; i < data.length; i++) {
- data[i] -= 32;
- System.out.print(data[i]+" ,");
- }
- System.out.println(new String(data));
- }
- }
- //編譯結果如下:
- //72 ,69 ,76 ,76 ,79 ,87 ,79 ,82 ,68 ,HELLOWORD
-
字串比較
不區分大小寫的比較方法 ( 比如輸入驗證碼 )
public boolean equalsIgnoreCase(String anotherString)
範例:
- public class Test {
- public static void main(String[] args) {
- String str1="helloword";
- String str2="HELLOWORD";
- System.out.println(str1.equals(str2));
- System.out.println(str1.equalsIgnoreCase(str2));
- }
- }
- //編譯結果如下:
- //false
- //true
-
比較兩個字串大小關係 *** 重要 ***
public int compareTo(String anotherString) ( 只需要比到第一個不同的字元即可 )
1. >0 : 表示本字串大於目標字串
2. =0 : 表示兩者相等
3. <0 : 表示本字串小於目標字串
範例:
- public class Test {
- public static void main(String[] args) {
- System.out.println("A".compareTo("a"));
- System.out.println("a".compareTo("A"));
- System.out.println("A".compareTo("A"));
- System.out.println("AB".compareTo("AC"));
- System.out.println("代".compareTo("李"));
- }
- }
- //編譯結果如下:
- //-32
- //32
- //0
- //1
- //-6251
-
字串查詢
從一個完整的字串當中判斷一個字串是否存在 *** 重要 ***
public Boolean contains(Sting str);
範例:
- public class Test {
- public static void main(String[] args) {
- String str="Helloworld";
- System.out.println(str.contains("world"));
- }
- }
- //編譯結果如下
- //true
判斷是否以指定字串開頭
public boolean startWith(String prefix)
public boolean startWith(String prefix,int toffset)toffset(偏移量)
判斷是否以指定字串結尾
public boolean endsWith(String suffix)
範例:
- public class Test {
- public static void main(String[] args) {
- String str="Helloworld";
- System.out.println(str.startsWith("H"));
- System.out.println(str.startsWith("l",2));
- System.out.println(str.startsWith("e"));
- System.out.println(str.endsWith("d"));
- }
- }
- //編譯結果如下:
- //true
- //true
- //false
- //true
-
字串替換
public String replaceAll(String regex,String replacement)
將目標字串全部替換
str.replaceAll(“l”,“_”):將str中的所有 "l" 換成 "_"
public String replaceFirst(String regex,String replacement)(替換首個)
範例:
- public class Test {
- public static void main(String[] args) {
- String str="helloworld";
- System.out.println(str.replaceAll("l","*"));
- System.out.println(str.replaceFirst("l","*"));
- }
- }
- //編譯結果如下:
- //he**owor*d
- //he*loworld
-
字串拆分 *** 重要 ***
將字串全部拆分
public String[] split(String regex)
將字串拆分成陣列長度為limit的字串陣列
public String[] split(String regex,int limit)
範例:
- public class Test{
- public static void main(String[] args){
- String str="hello world hello bit and you";
- String[] result=str.split(" ",2);
- //String[] result=str.split(" ",3);
- //String[] result=str.split(" ",4);
- //String[] result=str.split(" ",5);
- for(String s:result){
- System.out.print(s+" , ");
- }
- }
- }
- //編譯結果如下:
- //hello ,world hello bit and you
- //hello ,world, hello bit and you
- //hello ,world ,hello ,bit and you
- //hello ,world ,hello, bit, and you
特殊字元需要轉義後拆分 \\
eg:\\.
範例: 實現多次拆分 *** 重要 ***
- public class Test{
- public static void main(String[] args){
- String str="yum:21|hsd:176";
- String[] temp=str.split("\\|");
- for(int i=0;i<temp.length;i++){
- String name=temp[i].split(":")[0];
- String age=temp[i].split(":")[1];
- System.out.println("姓名為:"+name);
- System.out.println("年齡為:"+age);
- }
- }
- }
-
字串擷取 *** 重要 ***
從指定索引擷取到結尾
public Srting substring (int beginIndex)
從指定索引截部分內容 左閉右開 [ )
public String substring(int beginIndex,int endIndex)
範例:
- public class Test {
- public static void main(String[] args) {
- String str="helloworld";
- System.out.println(str.substring(5));
- System.out.println(str.substring(0,5));
- }
- }
- //world
- //hello
-
字串其他操作方法
去除字串左右空格,並且保留中間空格
public String trim() 可以與replaceAll配合使用 “ hello world ”
範例:
- public class Test {
- public static void main(String[] args) {
- String str=" hello world ";
- System.out.println("["+str+"]");
- System.out.println("["+str.trim()+"]");
- }
- }
- //[ hello world ]
- //[hello world]
字串轉大小寫(全部大小寫)(兩個函式只是在字母之間進行大小寫轉換)
public String toUpperCase() //轉大寫
public String toLowerCase() //轉小寫
範例:
- public class Test {
- public static void main(String[] args) {
- String str=" Ig 牛逼 ";
- System.out.println(str.toUpperCase());
- System.out.println(str.toLowerCase());
- }
- }
- // IG 牛逼
- // ig 牛逼
範例:只將首字母轉為大寫 先擷取,再轉 面試題: *** 重要 ***
- public class Test {
- public static void main(String[] args) {
- System.out.println(firstUpper("dyson"));
- System.out.println(firstUpper(""));
- System.out.println(firstUpper("a"));
- }
- public static String firstUpper(String str) {
- //首先要判斷str是否為空指標再接著判斷str是否為空字串
- //注意先後順序
- if(str==null||str.isEmpty()){
- return str;
- }
- //由於從指定索引截部分內容為左閉右開 [ ),所以當字串只有
- //一個字元時要特殊處理
- if(str.length()==1){
- return str.toUpperCase();
- }
- //先將字串中第一個字元截取出來並轉化為大寫,再將後面的字元
- //連線到該字元後邊
- return str.substring(0,1).toUpperCase()+str.substring(1);
- }
- }
- //Dyson A
- 判斷字串是否為空字串(“”,不判斷null,空指標)
public boolean isEmpty()
if(str==null | | str.isEmpty()){
//首先要判斷str是否為空指標再接著判斷str是否為空字串
//注意先後順序
}
範例:
- public class Test {
- public static void main(String[] args) {
- System.out.println("hello".isEmpty());
- System.out.println("".isEmpty());
- System.out.println(new String().isEmpty());
- }
- }
- //false true true