day10-字符串

目錄

  • 字符串
    • 1、API 和 API 幫助文檔
    • 2、String概述
    • 3、String構造方法代碼實現 和 內存分析
      • 3.1 創建String對象的兩種方式
      • 3.2 Java的內存模型
    • 4、字符串的比較
      • 4.1 ==號的作用
      • 4.2 equals方法的作用
    • 練習
      • 5、用戶登錄
      • 6、遍歷字符串和統計字符個數
      • 7、字符串拼接和翻轉
      • 8、較難練習-金額轉換
      • 9、手機號屏蔽
    • 10、StringBuilder
    • 11、StringJoiner
    • 12、字符串相關類的底層原理
      • 擴展底層原理1:字符串存儲的內存原理
      • 擴展底層原理2:==號比較的到底是什么?
      • 擴展底層原理3:字符串拼接的底層原理
      • 擴展底層原理4:StringBuilder提高效率原理圖
      • 擴展底層原理5:StringBuilder源碼分析
    • 練習
      • 13、較難練習-羅馬數字的兩種寫法
      • 14、調整字符串的內容并比較
      • 15、后續練習思路分析

字符串

1、API 和 API 幫助文檔

通過網盤分享的文件:資料
鏈接: https://pan.baidu.com/s/1jlQvGN1PHiud6NXhSYpIaA?pwd=reyn 提取碼: reyn

什么是API?
?API (Application Programming Interface) :應用程序編程接口。
簡單理解: API就是別人已經寫好的東西,我們不需要自己編寫,直接使用即可。

Java API:指的就是JDK中提供的各種功能的Java類。
這些類將底層的實現封裝了起來,我們不需要關心這些類是如何實現的,只需要學習這些類如何使用即可,我們可以通過幫助文檔來學習這些API如何使用。

**API幫助文檔:**幫助開發人員更好的使用API和查詢API的一個工具。

如何使用API幫助文檔

  • ①打開API幫助文檔
    在這里插入圖片描述

  • ②點擊顯示,找到索引選項卡中的輸入框
    在這里插入圖片描述

  • ③在輸入框中輸入 類名 并點擊顯示
    在這里插入圖片描述

  • ④查看類所在的包
    在這里插入圖片描述

  • ⑤查看類的描述
    在這里插入圖片描述

  • ⑥查看構造方法
    在這里插入圖片描述

  • ⑦查看成員方法
    在這里插入圖片描述

🍊API文檔練習:
需求:按照幫助文檔的使用步驟學習 Scanner 類的使用,并實現接收鍵盤錄入一個小數,最后輸出在控制臺.

public class ScannerDemo1 {public static void main(String[] args) {//1.創建對象Scanner sc = new Scanner(System.in);System.out.println("請輸入一個小數");//2.接收一個小數double result = sc.nextDouble();//3.輸出打印System.out.println(result);}
}

2、String概述

String 類代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被實現為此類的實例。也就是說,Java 程序中所有的雙引號字符串,都是 String 類的對象。
String 類在 java.lang 包下,所以使用的時候不需要導包!

String類的特點

  • 字符串不可變,它們的值在創建后不能被更改
  • 雖然 String 的值是不可變的,但是它們可以被共享
  • 字符串效果上相當于字符數組( char[] ),但是底層原理是字節數組( byte[] )
String name = "阿偉";
String schoolName = "黑馬程序員";
System.out.println(name + schoolName);
// 三個字符串
String name = "阿偉";
name = "三連.阿偉";
// 兩個字符串
// 不是改變了字符串的內容,而是創建了一個新的字符串,
// 把新的字符串復制給了前面的變量 name,此時并沒有改變第一個字符串里面的內容

3、String構造方法代碼實現 和 內存分析

3.1 創建String對象的兩種方式

1、直接賦值

2、通過構造方法

構造方法說明
public String()創建一個空白字符串對象,不含有任何內容
public String(String original)根據傳入的字符串,創建字符串對象
public String(char[] chs)根據字符數組的內容,來創建字符串對象
public String(byte[] bys)根據字節數組的內容,來創建字符串對象

🌰代碼示例:

public class StringDemo1 {public static void main(String[] args) {//1.使用直接賦值的方式獲取一個字符串對象String s1 = "abc";System.out.println(s1);//abc//2.使用new的方式來獲取一個字符串對象//public String():創建一個空白字符串對象,不含有任何內容//空參構造:可以獲取一個空白的字符串對象String s2 = new String();System.out.println("@" + s2 + "!");//"@!"//傳遞一個字符串,根據傳遞的字符串內容再創建一個新的字符串對象//這種方式只要知道有它存在就好了String s3 = new String("abc");System.out.println(s3);//public String(char[] chs):根據字符數組的內容,來創建字符串對象//傳遞一個字符數組,根據字符數組的內容再創建一個新的字符串對象//需求:我要修改字符串的內容。  abc --> Qbc//abc -->  {'a','b','c'}  -->  {'Q','b','c'} --> "Qbc"char[] chs = {'a', 'b', 'c', 'd'};String s4 = new String(chs);System.out.println(s4);//abcd//public String(byte[] bys):根據字節數組的內容,來創建字符串對象//傳遞一個字節數組,根據字節數組的內容再創建一個新的字符串對象//應用場景:以后在網絡當中傳輸的數據其實都是字節信息//我們一般要把字節信息進行轉換,轉成字符串,此時就要用到這個構造了。byte[] bytes = {97, 98, 99, 100};String s5 = new String(bytes);System.out.println(s5);//abcd}
}

通過構造方法創建字符串中,前面兩種方法少用,后面兩種方法以后用得上。

3.2 Java的內存模型

在這里插入圖片描述

串池,可以理解成 字符串常量池 ,但是只有 直接賦值 的字符串才存在這個 串池 中。

🍎直接賦值
在這里插入圖片描述

給 s1 賦值時系統會先去串池中觀察,有沒有abc,沒有的話就會創建一個新的abc,然后把她得 地址值 賦值給 s1。
給 s2 賦值時,串池已經有一個abc了,它就不會創建abc,而是會復用已經存在的abc。

??小結:
當使用雙引號直接賦值時,系統會檢查該字符串在串池中是否存在:
不存在:創建新的
存在:復用

🍎手動new出來的
在這里插入圖片描述

以字符數組為例,給 s1 賦值時遇到 new 關鍵字,在堆里面創建了一個小空間,這個小空間里面的內容就是字符數組的內容abc,然后再把這個小空間的地址值,賦給 s1,s1 通過地址值就能找到創建出來的字符串了。
給 s2 賦值時遇到 new 關鍵字,其實就是把上述過程重復了一遍,假設開辟出來的第三個小空間的地址值是 0x0033,此時就會把 0x0033 賦給 s2 ,s2 通過它就能找到第二個字符串對象。

??每new一次就會開辟一個小空間,不會復用。

4、字符串的比較

4.1 ==號的作用

  • 比較基本數據類型:比較的是具體的值
  • 比較引用數據類型:比較的是對象地址值
int a = 10;
int b = 20;
System.out.println(a == b); // falseString s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // false

4.2 equals方法的作用

  • 方法介紹
    • public boolean equals(String s)
      比較兩個字符串內容是否相同、區分大小
    • public boolean equalslgnoreCase(String s)
      比較兩個字符串內容是否相同、不區分大小寫

🌰代碼示例:

public class StringDemo2 {public static void main(String[] args) {//1.創建兩個字符串對象String s1 = new String("abc");String s2 = "Abc";//2.==號比較//基本數據類型:比的是數據值//引用數據類型:比的是地址值System.out.println(s1 == s2);//false//3.比較字符串對象中的內容是否相等boolean result1 = s1.equals(s2);System.out.println(result1); // false//4.比較字符串對象中的內容是否相等,忽略大小寫//1 一 壹 這不行//忽略大小寫只能是英文狀態下的a Aboolean result2 = s1.equalsIgnoreCase(s2);System.out.println(result2);//true}
}

練習

5、用戶登錄

需求:
已知用戶名和密碼,請用程序實現模擬用戶登錄。總共給三次機會,登錄之后,給出相應的提示。

📖代碼示例:

public class Test1登錄案例 {public static void main(String[] args) {//1.定義兩個變量用來記錄正確的用戶名和密碼String rightUsername = "itheima";String rightPassword = "1234qwer";//2.鍵盤錄入用戶名和密碼//ctrl + alt + T 選擇包裹方式for (int i = 0; i < 3; i++) {//0 1 2Scanner sc = new Scanner(System.in);System.out.println("請輸入用戶名");String username = sc.next();System.out.println("請輸入密碼");String password = sc.next();//3.判斷比較if (username.equals(rightUsername) && password.equals(rightPassword)) {System.out.println("登錄成功");//如果正確,循環結束break;} else {//最后一次機會if(i == 2){System.out.println("賬戶" + username + "被鎖定,請聯系黑馬程序員官方小姐姐:XXXXXXX");}else{//不是最后一次機會System.out.println("用戶名或密碼錯誤,登錄失敗,還剩下" + (2 - i) + "次機會");//2 1 0}}}}
}

6、遍歷字符串和統計字符個數

需求:
鍵盤錄入一個字符串,統計該字符串中大寫字母字符,小寫字母字符,數字字符出現的次數(不考慮其他字符)。

📖代碼示例:

public class Test4統計個數 {public static void main(String[] args) {//鍵盤錄入一個字符串,統計大寫,小寫,數字出現的次數//1.鍵盤錄入一個字符串Scanner sc = new Scanner(System.in);System.out.println("請輸入一個字符串");String str = sc.next();//2.統計 --- 計數器count//此時我要統計的有3樣東西,所以要定義3個計數器分別進行統計int bigCount = 0;int smallCount = 0;int numberCount = 0;//得到這個字符串里面每一個字符for (int i = 0; i < str.length(); i++) {//i 表示字符串中的索引//c 表示字符串中的每一個字符char c = str.charAt(i);//對c進行判斷if (c >= 'a' && c <= 'z') {smallCount++;}else if(c >= 'A' && c <= 'Z'){bigCount++;}else if(c >= '0' && c <= '9'){numberCount++;}}//3.當循環結束之后,三個變量記錄的就是對應的個數System.out.println("大寫字符有:" + bigCount + "個");System.out.println("小寫字符有:" + smallCount + "個");System.out.println("數字字符有:" + numberCount + "個");}
}

7、字符串拼接和翻轉

需求:
定義一個方法,把 int 數組中的數據按照指定的格式拼接成一個字符串返回,調用該方法,并在控制臺輸出結果。例如,數組為 int[] arr = {1,2,3}; ,執行方法后的輸出結果為:[1, 2, 3]。

📖代碼示例:

public class Test5數組拼接成字符串 {public static void main(String[] args) {//定義一個方法,把 int 數組中的數據按照指定的格式拼接成一個字符串返回,調用該方法,//并在控制臺輸出結果。例如,數組為 int[] arr = {1,2,3};//執行方法后的輸出結果為:[1, 2, 3]int[] arr = {1, 2, 3, 4, 5};String str = arrToString(arr);System.out.println(str);}//作用:把一個數組變成字符串public static String arrToString(int[] arr) {String s = "";//拼接左括號s = s + "["; //此時是拿著長度為0的字符串,跟[進行拼接,產生一個新的字符串。// *這里不用"s+",直接s ="["也可以,//把新的字符串再賦值給s,此時變量s記錄的就是新的字符串"["的地址值//下面我想得到數組里面的每一個元素并進行拼接//那么就需要遍歷數組,得到每一個元素才行for (int i = 0; i < arr.length; i++) {if(i == arr.length - 1){//如果是最后一個元素,那么不需要拼接逗號空格s = s + arr[i];}else{//如果不是最后一個元素,需要拼接元素和逗號空格s = s + arr[i] + ", ";}}//等循環結束之后,再拼接最后一個右括號s = s + "]";return s;}//用來遍歷數組public static void printArr(int[] arr) {System.out.print("[");for (int i = 0; i < arr.length; i++) {if (i == arr.length - 1) {System.out.print(arr[i]);} else {System.out.print(arr[i] + ", ");}}System.out.println("]");//[1, 2, 3, 4, 5]//我們現在要知道,這個最終結果是怎么來的?//從到右依次打印得來的。}
}

8、較難練習-金額轉換

需求:
把2135變成:零佰零拾零萬貳仟壹佰叁拾伍元
把789變成:零佰零拾零萬零仟柒佰捌拾玖元

📖代碼示例:

package com.itheima.stringdemo;import java.util.Scanner;public class StringDemo9 {public static void main(String[] args) {//1.鍵盤錄入一個金額Scanner sc = new Scanner(System.in);int money;while (true) {System.out.println("請錄入一個金額");money = sc.nextInt();if (money >= 0 && money <= 9999999) {break;} else {System.out.println("金額無效");}}//定義一個變量用來表示錢的大寫String moneyStr = "";//2.得到money里面的每一位數字,再轉成中文while (true) {//2135//從右往左獲取數據,因為右側是數據的個位int ge = money % 10;String capitalNumber = getCapitalNumber(ge);//把轉換之后的大寫拼接到moneyStr當中moneyStr = capitalNumber + moneyStr;//第一次循環 : "伍" + "" = "伍"//第二次循環 : "叁" + "伍" = "叁伍"//去掉剛剛獲取的數據money = money / 10;//如果數字上的每一位全部獲取到了,那么money記錄的就是0,此時循環結束if (money == 0) {break;}}//3.在前面補0,補齊7位int count = 7 - moneyStr.length();for (int i = 0; i < count; i++) {moneyStr = "零" + moneyStr;}System.out.println(moneyStr);//零零零貳壹叁伍//4.插入單位//定義一個數組表示單位String[] arr = {"佰","拾","萬","仟","佰","拾","元"};//               零    零   零   貳   壹   叁   伍//遍歷moneyStr,依次得到 零    零   零   貳   壹   叁   伍//然后把arr的單位插入進去String result = "";for (int i = 0; i < moneyStr.length(); i++) {char c = moneyStr.charAt(i);//把大寫數字和單位拼接到result當中result = result + c + arr[i]; // 零,零佰,零佰零,零佰零拾...}//5.打印最終結果System.out.println(result);}//定義一個方法把數字變成大寫的中文//1 -- 壹public static String getCapitalNumber(int number) {//定義數組,讓數字跟大寫的中文產生一個對應關系String[] arr = {"零", "壹", "貳", "叁", "肆", "伍", "陸", "柒", "捌", "玖"};//返回結果return arr[number];}
}

9、手機號屏蔽

需求:
以字符串的形式從鍵盤接受一個手機號,將中間四位號碼屏蔽。
最終效果為:131****9468

📖代碼示例:

public class Test8手機號屏蔽 {public static void main(String[] args) {/*以字符串的形式從鍵盤接受一個手機號,將中間四位號碼屏蔽最終效果為:131****9468*///1.鍵盤錄入一個手機號碼Scanner sc = new Scanner(System.in);System.out.println("請輸入手機號碼");String phoneNumber = sc.next();//13112349408//2.截取手機號碼中的前三位String star = phoneNumber.substring(0, 3);//3.截取手機號碼中的最后四位//此時我用substring方法,是用1個參數的,還是兩個參數的?1個參數的會更好//因為現在我要截取到最后,所以建議使用1個參數的。String end = phoneNumber.substring(7); // *從第 7 位到最后//4.拼接String result = star + "****" + end;System.out.println(result);}
}

10、StringBuilder

StringBuilder 可以看成是一個容器,創建之后里面的內容是可變的。

  • 作用:提高字符串的操作效率。
String s1 = "aaa";
String s2 = "bbb";
String s3 = "ccc";
String s4 = "ddd";
String s5 = "eee";String s6 = s1 + s2 + s3 + s4 + s5;
// 在拼接過程中會產生很多沒有用的字符串// 用StringBuilder,在拼接過程中不會產生那么多沒有用的字符串,所以用StringBuilder效率會更高。

??StringBuilder構造方法

方法名說明
public StringBuilder()創建一個空白可變字符串對象,不含有任何內容
public StringBuilder(String str)根據字符串的內容,來創建可變字符串對象

??StringBuilder常用方法

方法名說明
public StringBuilder append (任意類型)添加數據,并返回對象本身
public StringBuilder reverse()反轉容器中的內容
public int length0返回長度(字符出現的個數)
public String toString0通過toString()就可以實現把StringBuilder轉換為String

🌰代碼示例:

package com.itheima.stringbuilderdemo;public class StringBuilderDemo3 {public static void main(String[] args) {//1.創建對象StringBuilder sb = new StringBuilder("abc");//2.添加元素/*sb.append(1);sb.append(2.3);sb.append(true);*/// abc12.3true//反轉sb.reverse();//獲取長度int len = sb.length();System.out.println(len);//打印//普及://因為StringBuilder是Java已經寫好的類//java在底層對他做了一些特殊處理。//打印對象不是地址值而是屬性值。System.out.println(sb);}
}
package com.itheima.stringbuilderdemo;public class StringBuilderDemo4 {public static void main(String[] args) {//1.創建對象StringBuilder sb = new StringBuilder();//2.添加字符串sb.append("aaa").append("bbb").append("ccc").append("ddd");System.out.println(sb);//aaabbbcccddd//3.再把StringBuilder變回字符串String str = sb.toString();System.out.println(str);//aaabbbcccddd}
}

sb 只是一個容器,來幫助我們操作字符串的工具。所以在拼接完之后,還需要把 StringBuilder 變回 字符串 。

??鏈式編程
當我們在調用一個方法的時候,不需要用變量接收他的結果,可以繼續調用其他方法。

🌰代碼示例:

package com.itheima.stringbuilderdemo;import java.util.Scanner;public class StringBuilderDemo5 {public static void main(String[] args) {//鏈式編程://當我們在調用一個方法的時候,不需要用變量接收他的結果,可以繼續調用其他方法int len = getString().substring(1).replace("A", "Q").length();System.out.println(len);}public static String getString(){Scanner sc = new Scanner(System.in);System.out.println("請輸入一個字符串");String str = sc.next();return str;}
}

鏈式編程:依賴前一個方法的結果 再去調用后面的方法。
substring 截取完的結果是一個小的字符串,可以繼續調用字符串里面的方法 replace (把字符串里面的A替換成Q),然后再調用 length 獲取字符串的長度。

public class StringBuilderDemo4 {public static void main(String[] args) {//1.創建對象StringBuilder sb = new StringBuilder();//2.添加字符串sb.append("aaa").append("bbb").append("ccc").append("ddd");System.out.println(sb);//aaabbbcccddd//3.再把StringBuilder變回字符串String str = sb.toString();System.out.println(str);//aaabbbcccddd}
}

🍊練習:對稱字符串
需求:
鍵盤接受一個字符串,程序判斷出該字符串是否是對稱字符串,并在控制臺打印是或不是。

對稱字符串:123321、111
非對稱字符串:123123

📖代碼示例:

public class StringBuilderDemo6 {//使用StringBuilder的場景://1.字符串的拼接//2.字符串的反轉public static void main(String[] args) {//1.鍵盤錄入一個字符串Scanner sc = new Scanner(System.in);System.out.println("請輸入一個字符串");String str = sc.next();//2.反轉鍵盤錄入的字符串String result = new StringBuilder().append(str).reverse().toString();//3.比較if(str.equals(result)){System.out.println("當前字符串是對稱字符串");}else{System.out.println("當前字符串不是對稱字符串");}}
}

🍊練習:拼接字符串

需求:定義一個方法,把 int 數組中的數據按照指定的格式拼接成一個字符串返回。調用該方法,并在控制臺輸出結果。
例如:數組為 int[] arr = {1,2,3};
執行方法后的輸出結果為:[1, 2, 3]

📖代碼示例:

package com.itheima.stringbuilderdemo;public class StringBuilderDemo7 {public static void main(String[] args) {//1.定義數組int[] arr = {1,2,3};//2.調用方法把數組變成字符串String str = arrToString(arr);System.out.println(str);}public static String arrToString(int[] arr){StringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if(i == arr.length - 1){sb.append(arr[i]);}else{sb.append(arr[i]).append(", ");}}sb.append("]");return sb.toString();}
}

11、StringJoiner

  • StringJoiner跟StringBuilder一樣,也可以看成是一個容器,創建之后里面的內容是可變的。
  • 作用:提高字符串的操作效率,而且代碼編寫特別簡潔,但是目前市場上很少有人用。
  • JDK8出現的

??StringJoiner的構造方法

方法名說明
public StringJoiner (間隔符號)創建一個StringJoiner對象,指定拼接時的間隔符號
public StringJoiner (間隔符號,開始符號,結束符號)創建一個StringJoiner對象,指定拼接時的間隔符號、開始符號、結束符號

??StringJoiner的成員方法

方法名說明
public StringJoiner add (添加的內容)添加數據,并返回對象本身
public int length()返回長度(字符出現的個數)
public String toString()返回一個字符串(該字符串就是拼接之后的結果)

🌰代碼示例:

package com.itheima.stringjoinerdemo;import java.util.StringJoiner;public class StringJoinerDemo1 {public static void main(String[] args) {//1.創建一個對象,并指定中間的間隔符號StringJoiner sj = new StringJoiner("---");//2.添加元素sj.add("aaa").add("bbb").add("ccc");//3.打印結果System.out.println(sj);//aaa---bbb---ccc}
}
package com.itheima.stringjoinerdemo;import java.util.StringJoiner;public class StringJoinerDemo2 {public static void main(String[] args) {//1.創建對象StringJoiner sj = new StringJoiner(", ","[","]");//2.添加元素sj.add("aaa").add("bbb").add("ccc");int len = sj.length();System.out.println(len);//15 // *逗號后面還有個空格//3.打印System.out.println(sj);//[aaa, bbb, ccc]String str = sj.toString();System.out.println(str);//[aaa, bbb, ccc]}
}

🍎總結:

  1. String
    表示字符串的類,定義了很多操作字符串的方法。

  2. StringBuilder
    一個可變的操作字符串的容器。
    可以高效的拼接字符串,還可以將容器里面的內容反轉。

  3. StringJoiner
    JDK8出現的一個可變的操作字符串的容器,可以高效,方便的拼接字符串。
    在拼接的時候,可以制定間隔符號,開始符號,結束符號。

12、字符串相關類的底層原理

擴展底層原理1:字符串存儲的內存原理

  • 直接賦值會復用字符串常量池中的東西
  • new出來不會復用,而是開辟一個新的空間

擴展底層原理2:==號比較的到底是什么?

  • 基本數據類型比較數據值
  • 引用數據類型比較地址值

擴展底層原理3:字符串拼接的底層原理

第一種情況:等號的右邊沒有變量
在這里插入圖片描述

第二種情況:等號的右邊有變量
🍑畫圖解釋(JDK8以前):
在這里插入圖片描述

字符串 和 變量 一次拼接,堆內存中至少會出現兩個對象,一個是 StringBuilder對象,一個是 字符串String 對象。
String s2 = s1 + "b";,相當于是,new StringBuilder().append(s1).append("b").toString();,toString的底層原理是 new,所以內存中會有兩個對象。

在這里插入圖片描述

🍑畫圖解釋(JDK8):
在這里插入圖片描述

JDK8 在字符串拼接的時候會做一個 預估。預估成數組,最后再去創建字符串對象。

但是預估也是需要時間的,如果每一行都要進行 字符串和變量的拼接 的話,每一行都要進行預估,再創建數組,再變成字符串。

所以就算JDK優化了,還是一樣的浪費時間。字符串拼接的時候有變量參與,在內存中創建了很多對象浪費空間,時間也非常慢。

?結論:如果很多字符串變量拼接,不要直接+。在底層會創建多個對象,浪費時間,浪費性能。

擴展底層原理4:StringBuilder提高效率原理圖

🍑畫圖解釋:在這里插入圖片描述

StringBuilder是一個內容可變的容器,我們是把所有的數據往 同一個StringBuilder 里面放的,所以效率會高。

📝常見面試題:
1??
在這里插入圖片描述
📚答案:
在這里插入圖片描述

2??
在這里插入圖片描述
📚答案:
在這里插入圖片描述

??字符串原理小結:

擴展底層原理3:字符串拼接的底層原理

  • 如果沒有變量參與,都是字符串直接相加,編譯之后就是拼接之后的結果,會復用串池中的字符串。
  • 如果有變量參與,每一行拼接的代碼,都會在內存中創建新的字符串,浪費內存。

擴展底層原理4:StrinqBuilder提高效率原理圖

  • 所有要拼接的內容都會往StringBuilder中放,不會創建很多無用的空間,節約內存.

擴展底層原理5:StringBuilder源碼分析

  • 默認創建一個長度為16的字節數組
  • 添加的內容長度小于16,直接存
  • 添加的內容大于16會擴容(原來的容量*2+2)
  • 如果擴容之后還不夠,以實際長度為準

🌰代碼示例:

package test;import java.util.Scanner;public class A {public static void main(String[] args) {StringBuilder sb = new StringBuilder();// 容量:最多裝多少// 長度:已經裝了多少System.out.println(sb.capacity()); // 16System.out.println(sb.length()); // 0sb.append("abc");System.out.println(sb.capacity()); // 16System.out.println(sb.length()); // 3sb.append("defghijklmnopqrstuvwxyz");System.out.println(sb.capacity()); // 34System.out.println(sb.length()); // 26sb.append("0123456789");System.out.println(sb.capacity()); // 36System.out.println(sb.length()); // 36}
}

🍎字符串原理小結

擴展底層原理1:字符串存儲的內存原理

  • 直接賦值會復用字符串常量池中的東西
  • new出來不會復用,而是開辟一個新的空間

擴展底層原理2:==號比較的到底是什么?

  • 基本數據類型比較數據值
  • 引用數據類型比較地址值

擴展底層原理3:字符串拼接的底層原理

  • 如果沒有變量參與,都是字符串直接相加,編譯之后就是拼接之后的結果,會復用串池中的字符串。
  • 如果有變量參與,每一行拼接的代碼,都會在內存中創建新的字符串,浪費內存。

擴展底層原理4:StrinqBuilder提高效率原理圖

  • 所有要拼接的內容都會往StringBuilder中放,不會創建很多無用的空間,節約內存

擴展底層原理5:StringBuilder源碼分析

  • 默認創建一個長度為16的字節數組
  • 添加的內容長度小于16,直接存
  • 添加的內容大于16會擴容(原來的容量*2+2)
  • 如果擴容之后還不夠,以實際長度為準

練習

13、較難練習-羅馬數字的兩種寫法

鍵盤錄入一個字符串
要求1:長度為小于等于9
要求2:只能是數字
將內容變成羅馬數字
下面是阿拉伯數字跟羅馬數字的對比關系:
1-1、1-2、1-3、IV-4、V-5、V-6、V-7、V-8、1X-9注意點:
羅馬數字里面是沒有0的
如果鍵盤錄入的數字包含0,可以變成""(長度為0的字符串)

📖代碼示例:

package com.itheima.test;import java.util.Scanner;public class Test1Case1 {public static void main(String[] args) {/* 鍵盤錄入一個字符串,要求1:長度為小于等于9要求2:只能是數字將內容變成羅馬數字下面是阿拉伯數字跟羅馬數字的對比關系:Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9注意點:羅馬數字里面是沒有0的如果鍵盤錄入的數字包含0,可以變成""(長度為0的字符串)*///1.鍵盤錄入一個字符串//書寫Scanner的代碼Scanner sc = new Scanner(System.in);String str;while (true) {System.out.println("請輸入一個字符串");str = sc.next();//2.校驗字符串是否滿足規則boolean flag = checkStr(str);if (flag) {break;} else {System.out.println("當前的字符串不符合規則,請重新輸入");continue;}}//將內容變成羅馬數字//下面是阿拉伯數字跟羅馬數字的對比關系://Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9//查表法:數字跟數據產生一個對應關系StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);int number = c - 48; // 1 2 3 4 5String s = changeLuoMa(number);sb.append(s);}System.out.println(sb);}public static String changeLuoMa(int number) {//定義一個數組,讓索引跟羅馬數字產生一個對應關系String[] arr = {"", "Ⅰ", "Ⅱ", "Ⅲ", "Ⅳ", "Ⅴ", "Ⅵ", "Ⅶ", "Ⅷ", "Ⅸ"};return arr[number];}public static boolean checkStr(String str) {//123456//要求1:長度為小于等于9if (str.length() > 9) {return false;}//要求2:只能是數字for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);//0~9if (c < '0' || c > '9') {return false;}}//只有當字符串里面所有的字符全都判斷完畢了,我才能認為當前的字符串是符合規則return true;}
}
package com.itheima.test;import java.util.Scanner;public class Test1Case2 {public static void main(String[] args) {/* 鍵盤錄入一個字符串,要求1:長度為小于等于9要求2:只能是數字將內容變成羅馬數字下面是阿拉伯數字跟羅馬數字的對比關系:Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9注意點:羅馬數字里面是沒有0的如果鍵盤錄入的數字包含0,可以變成""(長度為0的字符串)*///1.鍵盤錄入一個字符串//書寫Scanner的代碼Scanner sc = new Scanner(System.in);String str;while (true) {System.out.println("請輸入一個字符串");str = sc.next();//2.校驗字符串是否滿足規則boolean flag = checkStr(str);if (flag) {break;} else {System.out.println("當前的字符串不符合規則,請重新輸入");continue;}}//將內容變成羅馬數字//下面是阿拉伯數字跟羅馬數字的對比關系://Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9//查表法:數字跟數據產生一個對應關系StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);String s = changeLuoMa(c);sb.append(s);}System.out.println(sb);}//利用switch進行匹配public static String changeLuoMa(char number) {return switch (number) {case '0' -> "";case '1' -> "Ⅰ";case '2' -> "Ⅱ";case '3' -> "Ⅲ";case '4' -> "Ⅳ";case '5' -> "Ⅴ";case '6' -> "Ⅵ";case '7' -> "Ⅶ";case '8' -> "Ⅷ";case '9' -> "Ⅸ";// *修正:直接返回空字符串// *這部分有報錯default -> "";};}public static boolean checkStr(String str) {//123456//要求1:長度為小于等于9if (str.length() > 9) {return false;}//要求2:只能是數字for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);//0~9if (c < '0' || c > '9') {return false;}}//只有當字符串里面所有的字符全都判斷完畢了,我才能認為當前的字符串是符合規則return true;}
}

14、調整字符串的內容并比較

給定兩個字符串,A 和 B。
A 的旋轉操作就是將 A最左邊的字符移動到最右邊。例如,若 A=‘abcde’,在移動一次之后結果就是’bcdea’如果在若干次調整操作之后,A能變成B,那么返回True。如果不能匹配成功,則返回false。

📖代碼示例:

package com.itheima.test;public class Test2Case1 {public static void main(String[] args) {/* 給定兩個字符串, A和B。A的旋轉操作就是將A 最左邊的字符移動到最右邊。例如, 若A = 'abcde',在移動一次之后結果就是'bcdea'如果在若干次調整操作之后,A能變成B,那么返回True。如果不能匹配成功,則返回false*///1.定義兩個字符串String strA = "abcde";String strB = "ABC";//2.調用方法進行比較boolean result = check(strA, strB);//3.輸出System.out.println(result);}public static boolean check(String strA, String strB) {for (int i = 0; i < strA.length(); i++) {strA = rotate(strA);if(strA.equals(strB)){return true;}}//所有的情況都比較完畢了,還不一樣那么直接返回falsereturn false;}//作用:旋轉字符串,把左側的字符移動到右側去//形參:旋轉前的字符串//返回值:旋轉后的字符串public static String rotate(String str) {//套路://如果我們看到要修改字符串的內容//可以有兩個辦法://1.用subString進行截取,把左邊的字符截取出來拼接到右側去//2.可以把字符串先變成一個字符數組,然后調整字符數組里面數據,最后再把字符數組變成字符串。//截取思路//獲取最左側那個字符char first = str.charAt(0);//獲取剩余的字符String end = str.substring(1);return end + first;}
}
package com.itheima.test;public class Test2Case2 {public static void main(String[] args) {/* 給定兩個字符串, A和B。A的旋轉操作就是將A 最左邊的字符移動到最右邊。例如, 若A = 'abcde',在移動一次之后結果就是'bcdea'如果在若干次調整操作之后,A能變成B,那么返回True。如果不能匹配成功,則返回false*///1.定義兩個字符串String strA = "abcde";String strB = "ABC";//2.調用方法進行比較boolean result = check(strA, strB);//3.輸出System.out.println(result);}public static boolean check(String strA, String strB) {for (int i = 0; i < strA.length(); i++) {strA = rotate(strA);if (strA.equals(strB)) {return true;}}//所有的情況都比較完畢了,還不一樣那么直接返回falsereturn false;}//作用:旋轉字符串,把左側的字符移動到右側去//形參:旋轉前的字符串//返回值:旋轉后的字符串public static String rotate(String str) {//套路://如果我們看到要修改字符串的內容//可以有兩個辦法://1.用subString進行截取,把左邊的字符截取出來拼接到右側去//2.可以把字符串先變成一個字符數組,然后調整字符數組里面數據,最后再把字符數組變成字符串。//可以把字符串先變成一個字符數組,然后調整字符數組里面數據,最后再把字符數組變成字符串。//"ABC"   ['A','B','C']  ['B','C','A']   new String(字符數組);char[] arr = str.toCharArray();//拿到0索引上的字符char first = arr[0];//把剩余的字符依次往前挪一個位置for (int i = 1; i < arr.length; i++) {arr[i - 1] = arr[i];}//把原來0索引上的字符放到最后一個索引arr[arr.length - 1] = first;//利用字符數組創建一個字符串對象String result = new String(arr);return result;}
}

15、后續練習思路分析

1??鍵盤輸入任意字符串,打亂里面的內容
📖代碼示例:

package com.itheima.test;public class Test3 {public static void main(String[] args) {//鍵盤輸入任意字符串,打亂里面的內容//1.鍵盤輸入任意字符串String str = "abcdefg";//2.打亂里面的內容//修改字符串里面的內容://1.subString//2.變成字符數組char[] arr = str.toCharArray();//['a','b','c','d','e','f','g']//3.打亂數組里面的內容//從0索引開始,跟一個隨機索引進行位置的交換//當數組里面的每一個元素都跟一個隨機索引進行交換完畢之后,那么內容就打亂了//4.把字符數組再變回字符串String result = new String(arr);System.out.println(result);}
}

2??生成驗證碼

內容:可以是小寫字母,也可以是大寫字母,還可以是數字

規則:長度為5。
內容中是四位字母,1位數字。
其中數字只有1位,但是可以出現在任意的位置。

📖代碼示例:

package com.itheima.test;public class Test4 {public static void main(String[] args) {/*生成驗證碼內容:可以是小寫字母,也可以是大寫字母,還可以是數字規則:長度為5內容中是四位字母,1位數字。其中數字只有1位,但是可以出現在任意的位置。*///1.可以把所有的大寫字母,小寫字母都放到一個數組當中char[] arr = new char[52];//a-z  A-Z//2.從數組中隨機獲取4次//3.生成一個0~9之間的隨機數拼接到最后//ACFG7//思考,我們把7放到前面,修改了字符串的內容//把生成的驗證碼先變成一個字符數組//再讓最后一個元素跟前面的隨機位置的元素進行交換//交換完畢之后再變成字符串就可以了。}
}

3??
給定兩個以字符串形式表示的非負整數num1和num2,返回num1和num2的乘積,它們的乘積也表示為字符串形式。
注意:需要用已有的知識完成。

📖代碼示例:

package com.itheima.test;public class Test5 {public static void main(String[] args) {/* 給定兩個以字符串形式表示的非負整數num1和num2,返回num1和num2的乘積,它們的乘積也表示為字符串形式。注意:需要用已有的知識完成。*///不需要考慮乘積過大之后的結果//就認為乘積一定是小于int的最大值的String num1 = "123456789";String num2 = "12345";//1.把num1和num2變成對應的整數才可以//"123456789"//先遍歷字符串依次得到每一個字符 '1'  '2'  '3'  '4'  '5'  '6'  '7'  '8'  '9'//再把字符變成對應的數字即可     1    2    3     4    5    6    7    8    9//把每一個數字組合到一起 123456789//2.利用整數進行相乘//3.可以把整數變成字符串//+""}
}

4??
給你一個字符串 s,由若干單詞組成,單詞前后用一些空格字符隔開。
返回字符串中最后一個單詞的長度。
單詞是指僅由字母組成、不包含任何空格字符的最大子字符串。

📖代碼示例:

package com.itheima.test;public class Test6 {public static void main(String[] args) {/* 給你一個字符串 s,由若干單詞組成,單詞前后用一些空格字符隔開。返回字符串中最后一個單詞的長度。單詞是指僅由字母組成、不包含任何空格字符的最大子字符串。示例 1:輸入:s = "Hello World“	輸出:5解釋:最后一個單詞是“World”,長度為5。示例 2:輸入:s = "   fly me   to   the moon"	輸出:4解釋:最后一個單詞是“moon”,長度為4。示例 3:輸入:s = "luffy is still joyboy"	輸出:6解釋:最后一個單詞是長度為6的“joyboy”。*///倒著遍歷//直到遇到空格為止//那么遍歷的次數就是單詞的長度}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895197.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895197.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895197.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

互聯網協議套件中的服務類型(RFC 1349)技術解析與總結

1. 背景與核心目標 RFC 1349 是對 IP 協議頭部 服務類型&#xff08;Type of Service, TOS&#xff09;字段語義的更新與澄清文檔&#xff0c;發布于 1992 年。其主要目標包括&#xff1a; 重新定義 TOS 字段的用途&#xff1a;明確 TOS 字段的語義&#xff0c;解決歷史標準中的…

使用git commit時‘“node“‘ 不是內部或外部命令,也不是可運行的程序

第一種&#xff1a; 使用git commit -m "xxx"時會報錯&#xff0c;我看網上的方法是在命令行后面添加--no-verify&#xff1a;git commit -m "主題更新" --no-verify&#xff0c;但是不可能每次都添加。 最后解決辦法是&#xff1a;使用git config --lis…

DeepSeek從入門到精通:全面掌握AI大模型的核心能力

文章目錄 一、DeepSeek是什么&#xff1f;性能對齊OpenAI-o1正式版 二、Deepseek可以做什么&#xff1f;能力圖譜文本生成自然語言理解與分析編程與代碼相關常規繪圖 三、如何使用DeepSeek&#xff1f;四、DeepSeek從入門到精通推理模型推理大模型非推理大模型 快思慢想&#x…

洛谷P3397 地毯(二維差分加暴力法)

題目難度&#xff1a;普及一 題目傳送門 地毯 題目描述 在 n n n\times n nn 的格子上有 m m m 個地毯。 給出這些地毯的信息&#xff0c;問每個點被多少個地毯覆蓋。 輸入格式 第一行&#xff0c;兩個正整數 n , m n,m n,m。意義如題所述。 接下來 m m m 行&#…

使用OBS推流,大華攝像頭 srs服務器播放

說明&#xff1a; ffmpeg可以推流&#xff0c;但是是命令行方式不太友好&#xff0c;還可以使用主流的OBS開源推流軟件&#xff0c;可從官網Open Broadcaster Software | OBS 下載最新版本&#xff0c;目前很多網絡主播都是用它做直播。該軟件支持本地視頻文件以及攝像頭推流。…

從大規模惡意攻擊 DeepSeek 事件看 AI 創新隱憂:安全可觀測體系建設刻不容緩

作者&#xff1a;羿莉&#xff08;蕭羿&#xff09; 全球出圈的中國大模型 DeepSeek 作為一款革命性的大型語言模型&#xff0c;以其卓越的自然語言處理能力和創新性成本控制引領行業前沿。該模型不僅在性能上媲美 OpenAI-o1&#xff0c;而且在推理模型的成本優化上實現了突破…

mac下dify+deepseek部署,實現私人知識庫

目前deepseek 十分火爆&#xff0c;本地部署實現私有知識庫&#xff0c;幫助自己日常工作&#xff0c;上一篇使用工具cherry studio可以做到私人知識庫。今天學習了一下&#xff0c;使用Dify鏈接deepseek&#xff0c;實現私人知識庫&#xff0c;也非常不錯&#xff0c;這里分享…

C++性能優化—人工底稿版

C以高性能著稱&#xff0c;性能優化是C程序員繞不過去的一個話題&#xff0c;性能優化是一個復雜、全局而又細節的問題&#xff0c;本文總結C性能分析中常用的知識。 性能優化的時機 大部分關于性能優化的文章都強調&#xff1a;不要過早的進行性能優化。 C編碼層面 數據結…

react概覽webpack基礎

react概覽 課程介紹 webpack 構建依賴圖->bundle 首屏渲染&#xff1a; 減少白屏等待時間 數據、結構、樣式都返回。需要服務器的支持 性能優化 ***webpack干的事情 模塊化開發 優勢&#xff1a; 多人團隊協作開發 可復用 單例&#xff1a;全局沖突 閉包 模塊導入的順序 req…

ASP.NET Core SignalR實踐指南

Hub類的生命周期是瞬態的&#xff0c;每次調用集線器的時候都會創建一個新的Hub類實例&#xff0c;因此不要在Hub類中通過屬性、成員變量等方式保存狀態。如果服務器的壓力比較大&#xff0c;建議把ASP.NET Core程序和SignalR服務器端部署到不同服務器上&#xff0c;以免它們互…

常見的九種二極管

常見的九種二極管 文章目錄 常見的九種二極管1、普通二極管2、光電二極管&#xff08;LED&#xff09;3、變容二級管4、發光二極管5、恒流二極管6、快恢復二極管&#xff08;FRD&#xff09;7、肖特基二極管8、瞬態電壓抑制二極管(TVS)9、齊納二極管&#xff08;穩壓&#xff0…

LabVIEW在呼吸機測試氣體容量計算

在呼吸機測試中&#xff0c;精確測量氣體容量變化是評估設備性能的關鍵步驟。通過監測呼吸機氣道內的壓力變化&#xff0c;并結合流阻和肺順應性等參數&#xff0c;可以計算出單位時間內的氣體容量變化。本案例基于LabVIEW實現該計算過程&#xff0c;以確保測試數據的準確性和一…

本地部署DeepSeek R1 + 界面可視化open-webui

本地部署DeepSeek R1 界面可視化open-webui ollama是物理機本地安裝 open-webui是容器啟動 另外&#xff0c;用docker 部署ollama也很方便ollama docker 安裝部署ollama ollama官網 安裝 Linux上安裝: curl -fsSL https://ollama.com/install.sh | sh使用命令行管理 拉…

第四十九章:橫店之旅:穿越時空的歡樂時光

自黃山之行結束后&#xff0c;小冷一家又回歸到了忙碌而又溫馨的日常生活中。小冷在杭州灣研發總部的工作愈發忙碌&#xff0c;項目一個接著一個&#xff0c;時常需要加班加點&#xff0c;但每當他回到家中&#xff0c;看到小澤澤可愛的笑臉和小一充滿活力的身影&#xff0c;一…

Python3 ImportError: cannot import name ‘XXX‘ from ‘XXX‘

個人博客地址&#xff1a;Python3 ImportError: cannot import name XXX from XXX | 一張假鈔的真實世界 例如如下錯誤&#xff1a; $ python3 git.py Traceback (most recent call last):File "git.py", line 1, in <module>from git import RepoFile &quo…

使用C語言實現MySQL數據庫的增刪改查操作指南

使用C語言與MySQL數據庫進行交互,通常涉及使用MySQL提供的C API庫。這套API允許開發者在C/C++程序中執行SQL查詢,從而實現數據庫的增刪改查操作。下面,我將詳細介紹如何在C語言中實現這些基本操作。 準備工作 安裝MySQL開發庫:確保你的系統上安裝了MySQL服務器以及MySQL開發…

局域網使用Ollama(Linux)

解決局域網無法連接Ollama服務的問題 在搭建和使用Ollama服務的過程中&#xff0c;可能會遇到局域網內無法連接的情況。經過排查發現&#xff0c;若開啟了代理軟件&#xff0c;尤其是Hiddify&#xff0c;會導致此問題。這一發現耗費了我數小時的排查時間&#xff0c;希望能給大…

在CT107D單片機綜合訓練平臺上實現外部中斷控制LED閃爍

引言 在單片機開發中&#xff0c;外部中斷是一個非常重要的功能&#xff0c;它可以讓單片機在檢測到外部信號變化時立即做出響應。本文將詳細介紹如何在CT107D單片機綜合訓練平臺上使用外部中斷來控制LED燈的閃爍。我們將使用兩種不同的方式來實現這一功能&#xff1a;一種是在…

重磅發布!AI 驅動的 Java 開發框架:Spring AI Alibaba

*本文作者系阿里云云原生微服務技術負責人&#xff0c;Spring AI Alibaba 發起人彥林&#xff0c;望陶和隆基對可觀測和 RocketMQ 部分內容亦有貢獻。 * 摘要 隨著生成式 AI 的快速發展&#xff0c;基于 AI 開發框架構建 AI 應用的訴求迅速增長&#xff0c;涌現出了包括 Lang…

防御保護作業二

拓撲圖 需求 需求一&#xff1a; 需求二&#xff1a; 需求三&#xff1a; 需求四&#xff1a; 需求五&#xff1a; 需求六&#xff1a; 需求七&#xff1a; 需求分析 1.按照要求進行設備IP地址的配置 2.在FW上開啟DHCP功能&#xff0c;并配置不同的全局地址池&#xff0c;為…