1.1String類概述
String 類代表字串,Java 程式中的所有字串文字(例如“abc”)都被實現為此類的例項。也就是說,Java 程式中所有的雙引號字串,都是 String 類的物件。String 類在 java.lang 包下,所以使用的時候不需要導包!
1.2String類的特點
- 字串不可變,它們的值在建立後不能被更改
- 雖然 String 的值是不可變的,但是它們可以被共享
- 字串效果上相當於字元陣列( char[] ),但是底層原理是位元組陣列( byte[] )
1.3String類的構造方法
常用的構造方法
方法名 說明 public String() 建立一個空白字串物件,不含有任何內容 public String(char[] chs) 根據字元陣列的內容,來建立字串物件 public String(byte[] bys) 根據位元組陣列的內容,來建立字串物件 String s = “abc”; 直接賦值的方式建立字串物件,內容就是abc 示例程式碼
public class StringDemo01 { public static void main(String[] args) { //public String():建立一個空白字串物件,不含有任何內容 String s1 = new String(); System.out.println("s1:" + s1); //public String(char[] chs):根據字元陣列的內容,來建立字串物件 char[] chs = {'a', 'b', 'c'}; String s2 = new String(chs); System.out.println("s2:" + s2); //public String(byte[] bys):根據位元組陣列的內容,來建立字串物件 byte[] bys = {97, 98, 99}; String s3 = new String(bys); System.out.println("s3:" + s3); //String s = “abc”; 直接賦值的方式建立字串物件,內容就是abc String s4 = "abc"; System.out.println("s4:" + s4); } }
1.4建立字串物件兩種方式的區別
透過構造方法建立
透過 new 建立的字串物件,每一次 new 都會申請一個記憶體空間,雖然內容相同,但是地址值不同
直接賦值方式建立
以“”方式給出的字串,只要字元序列相同(順序和大小寫),無論在程式程式碼中出現幾次,JVM 都只會建立一個 String 物件,並在字串池中維護
1.5字串的比較
1.5.1==號的作用
- 比較基本資料型別:比較的是具體的值
- 比較引用資料型別:比較的是物件地址值
1.5.2equals方法的作用
方法介紹
public boolean equals(String s) 比較兩個字串內容是否相同、區分大小寫
示例程式碼
public class StringDemo02 { public static void main(String[] args) { //構造方法的方式得到物件 char[] chs = {'a', 'b', 'c'}; String s1 = new String(chs); String s2 = new String(chs); //直接賦值的方式得到物件 String s3 = "abc"; String s4 = "abc"; //比較字串物件地址是否相同 System.out.println(s1 == s2); System.out.println(s1 == s3); System.out.println(s3 == s4); System.out.println("--------"); //比較字串內容是否相同 System.out.println(s1.equals(s2)); System.out.println(s1.equals(s3)); System.out.println(s3.equals(s4)); } }
1.6使用者登入案例
1.6.1案例需求
已知使用者名稱和密碼,請用程式實現模擬使用者登入。總共給三次機會,登入之後,給出相應的提示
1.6.2程式碼實現
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 2
Scanner 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
}
}
}
}
}
1.7遍歷字串案例
1.7.1案例需求
鍵盤錄入一個字串,使用程式實現在控制檯遍歷該字串
1.7.2直接遍歷字串
public class Test2字串直接遍歷 {
public static void main(String[] args) {
//兩個方法:
//charAt():會根據索引獲取對應的字元
//length(): 會返回字串的長度
//1.鍵盤錄入一個字串
Scanner sc = new Scanner(System.in);
System.out.println("請輸入字串");
String str = sc.next();
System.out.println(str);
//2.遍歷
for (int i = 0; i < str.length(); i++) {
//i 依次表示字串的每一個索引
//索引的範圍:0 ~ 長度-1
//根據索引獲取字串裡面的每一個字元
//ctrl + alt + V 自動生成左邊的接受變數
char c = str.charAt(i);
System.out.println(c);
}
}
}
1.8統計字元次數案例
1.8.1案例需求
鍵盤錄入一個字串,統計該字串中大寫字母字元,小寫字母字元,數字字元出現的次數(不考慮其他字元)
1.8.2程式碼實現
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 + "個");
}
}
1.9字串拼接案例
1.9.1案例需求
定義一個方法,把 int 陣列中的資料按照指定的格式拼接成一個字串返回,呼叫該方法,
並在控制檯輸出結果。例如,陣列為 int[] arr = {1,2,3}; ,執行方法後的輸出結果為:[1, 2, 3]
1.9.2程式碼實現
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記錄的就是新的字串"["的地址值
//下面我想得到陣列裡面的每一個元素並進行拼接
//那麼就需要遍歷陣列,得到每一個元素才行
for (int i = 0; i < arr.length; i++) {
//假設第一次迴圈:i = 0 獲取的就是0索引上的元素
//在拼接的時候:"[" + 1 + ", " 拼接完畢之後產生一個新的字串 "[1, "
//第二次迴圈:i = 1 獲取的就是1索引上的元素
//在拼接的時候: 此時s就是第一次迴圈結束後拼接完畢的結果:"[1, "
//在拼接的時候:"[1, " + 2 + ", " 拼接完畢之後產生一個新的字串 "[1, 2, "
//...
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]
//我們現在要知道,這個最終結果是怎麼來的?
//從到右依次列印得來的。
}
}
1.10字串反轉案例
1.10.1案例需求
定義一個方法,實現字串反轉。鍵盤錄入一個字串,呼叫該方法後,在控制檯輸出結果
例如,鍵盤錄入 abc,輸出結果 cba
1.10.2程式碼實現
public class Test6反轉字串 {
public static void main(String[] args) {
/*定義一個方法,實現字串反轉。鍵盤錄入一個字串,呼叫該方法後,在控制檯輸出結果
例如,鍵盤錄入 abc,輸出結果 cba*/
//1.定義一個字串
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個字串");
String str = sc.next();
//2.定義一個方法,反轉字串
//abc ---> cba
//可以把字串倒著遍歷,再拼接
String result = reverse(str);
System.out.println(result);
}
//註釋:方法的作用就是反轉字串
//把傳遞進來的字串進行反轉
public static String reverse(String str){//abc
//核心思想:倒著遍歷並進行拼接就可以了
//fori :正著遍歷 forr:倒著遍歷
String s = "";
for (int i = str.length() - 1; i >= 0; i--) {
//i 依次表示字串裡面的每一個索引(倒著的)
//我們就可以拿到裡面的每一個字元並拼接
s = s + str.charAt(i);
}
//把倒著拼接之後的結果返回即可
return s;
}
}
1.11 金額轉換
1.11.1 案例需求
把2135變成:零佰零拾零萬貳仟壹佰叄拾伍元
把789變成:零佰零拾零萬零仟柒佰捌拾玖元
1.11.2 程式碼實現
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];
}
}
1.12 手機號遮蔽
需求:以字串的形式從鍵盤接受一個手機號,將中間四位號碼遮蔽
最終效果為: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);
//4.拼接
String result = star + "****" + end;
System.out.println(result);
}
}
1.13 敏感詞替換
需求1:鍵盤錄入一個 字串,如果字串中包含(TMD),則使用*替換
public class Test9敏感詞替換 {
public static void main(String[] args) {
//1.定義一個變數表示罵人的話
String talk = "後裔你玩什麼啊,TMD";
//2.把這句話中的敏感詞進行替換
String result = talk.replace("TMD", "***");
//3.列印
System.out.println(talk);
System.out.println(result);
}
}
需求2:如果要替換的敏感詞比較多怎麼辦?
public class Test10多個敏感詞替換 {
public static void main(String[] args) {
//實際開發中,敏感詞會有很多很多
//1.先鍵盤錄入要說的話
Scanner sc = new Scanner(System.in);
System.out.println("請輸入要說的話");
String talk = sc.next();//後裔你玩什麼啊,TMD,GDX,ctmd,ZZ
//2.定義一個陣列用來存多個敏感詞
String[] arr = {"TMD","GDX","ctmd","ZZ","lj","FW","nt"};
//3.把說的話中所有的敏感詞都替換為***
for (int i = 0; i < arr.length; i++) {
//i 索引
//arr[i] 元素 --- 敏感詞
talk = talk.replace(arr[i],"***");
}
//4.列印結果
System.out.println(talk);//後裔你玩什麼啊,***,***,***,***
}
}
1.14 身份證資訊檢視
身份證的每一位都是有固定的含義:
- 1、2位:省份
- 3、4位:城市
- 5、6位:區縣
- 7-14位:出生年、月、日
- 15、16位:所在地派出所
- 17位:性別(奇數男性,偶數女性)
- 18位:個人資訊碼(隨機產生)
要求列印內容方式如下:
人物資訊為:
出生年月日:XXXX年X月X日
性別為:男/女
package com.itheima.stringdemo;
public class StringDemo11 {
public static void main(String[] args) {
//1.定義一個字串記錄身份證號碼
String id = "321281202001011234";
//2.獲取出生年月日
String year = id.substring(6, 10);
String month = id.substring(10, 12);
String day = id.substring(12, 14);
System.out.println("人物資訊為:");
System.out.println("出生年月日:" + year + "年" + month + "月" + day + "日");
//3.獲取性別
char gender = id.charAt(16);//'3' ---> 3
//利用ASCII碼錶進行轉換
//'0' ---> 48
//'1' ---> 49
//'2' ---> 50
//'3' ---> 51
//'4' ---> 52
//'5' ---> 53
//'6' ---> 54
//'7' ---> 55
//'8' ---> 56
//'9' ---> 57
int num = gender - 48;
if(num % 2 == 0){
System.out.println("性別為:女");
}else{
System.out.println("性別為:男");
}
}
}
2.StringBuilder
StringBuilder 可以看成是一個容器,建立之後裡面的內容是可變的。
當我們在拼接字串和反轉字串的時候會使用到
2.1 基本使用
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);*/
//反轉
sb.reverse();
//獲取長度
int len = sb.length();
System.out.println(len);
//列印
//普及:
//因為StringBuilder是Java已經寫好的類
//java在底層對他做了一些特殊處理。
//列印物件不是地址值而是屬性值。
System.out.println(sb);
}
}
2.2 鏈式程式設計
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
}
}
2.3 練習1:對稱字串
需求:
鍵盤接受一個字串,程式判斷出該字串是否是對稱字串,並在控制檯列印是或不是
對稱字串: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("當前字串不是對稱字串");
}
}
}
2.4 練習2:拼接字串
需求:定義一個方法,把 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();
}
}
3. StringJoiner
- StringJoiner跟StringBuilder一樣,也可以看成是一個容器,建立之後裡面的內容是可變的。
- 作用:提高字串的操作效率,而且程式碼編寫特別簡潔,但是目前市場上很少有人用。
- JDK8出現的
基本使用:
//1.建立一個物件,並指定中間的間隔符號
StringJoiner sj = new StringJoiner("---");
//2.新增元素
sj.add("aaa").add("bbb").add("ccc");
//3.列印結果
System.out.println(sj);//aaa---bbb---ccc
//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]
關於字串的小擴充套件:
字串儲存的記憶體原理
String s = “abc”;直接賦值
特點:
此時字串abc是存在字串常量池中的。
先檢查字串常量池中有沒有字串abc,如果有,不會建立新的,而是直接複用。如果沒有abc,才會建立一個新的。
所以,直接賦值的方式,程式碼簡單,而且節約記憶體。
new出來的字串
看到new關鍵字,一定是在堆裡面開闢了一個小空間。
String s1 = new String(“abc”);
String s2 = “abc”;
s1記錄的是new出來的,在堆裡面的地址值。
s2是直接賦值的,所以記錄的是字串常量池中的地址值。
==號比較的到底是什麼?
如果比較的是基本資料型別:比的是具體的數值是否相等。
如果比較的是引用資料型別:比的是地址值是否相等。
結論:==只能用於比較基本資料型別。不能比較引用資料型別。