Java-----String類

1.String類的重要性

經過了C語言的學習,我們認識了字符串,但在C語言中,我們表示字符串進行操作的話需要通過字符指針或者字符數組,可以使用標準庫中提供的一系列方法對字符串的內容進行操作,但這種表達和操作數據的方法不太符合面向對象的思想,所以在Java中提供了String類。

2. 認識String類

349fdcf11fd44c86adeb4c3afe06257c.png

在Java中,String類是一種存儲字符串數據類型的類。在Java中,String類屬于引用數據類型,由String類創建的對象里面存的是引用。

2.1 字符串構造

在Java中,字符串的構造有很多種方式,常用的就以下三種。

public class Test {public static void main(String[] args) {//使用常量直接構造String s1="haha";System.out.println(s1);//直接new String對象String s2=new String("man");System.out.println(s2);//使用字符數組進行構造char[] array={'w','c','I','s'};String s3=new String(array);System.out.println(s3);}
}

運行代碼

c6d84f77301a40f68ca6a9e5af781e07.png

2.2 深刻認識String類

我們知道String類的對象里面存的是引用,那字符串的內容具體是存在哪里的呢?

8e79d4e919a3486a85f57d07c554ef05.png

上圖是String類里面的一些具體細節,發現里面有一個char[ ]?value數組,所以字符串就是存儲在這個數組中。

String類的堆棧圖

b445ddec0a944569bb0851ed669065ac.png

2.3 String類的比較?

?1. 用 == 比較

當我們用 == 進行String類的對象進行比較時,是比較對象里面存的引用的值。

public class Test {public static void main(String[] args) {String s1="man";String s2=new String("man");String s3=s1;System.out.println(s1==s2);System.out.println(s1==s3);System.out.println(s2==s3);}
}

fa84433567e84ee3b4a94353aa8fe468.png

2. equal()方法比較

用equal方法比較String類的對象時,比較的是對象的字符串的內容是否相同。

public class Test {public static void main(String[] args) {String s1="haha";String s2=new String("man");String s3=s1;System.out.println(s1.equals(s2));System.out.println(s1.equals(s3));System.out.println(s2.equals(s3));}
}

66b23aedaa17494c9026e130be74c422.png

?3.int compareTo(String s)方法比較

1.當我們使用 int compareTo(String s) 方法比較時,比較的規則是:兩個字符串對應位置上的的字母比較,直到比到對應的字母不同時,看哪個字母的ASCII值大,對應的那個字符串就長。就直接放回對應兩個字母的ASCII值的差值。

2.當比較的兩個字符串的長度不一樣,一個長,一個短,假設短的字符串的長度為k,如果短的字符串的k個字符的內容與長字符串前k個字符相同,則放回兩個字符串的差值。

public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("ac");String s3 = new String("abc");String s4 = new String("abcdef");System.out.println(s1.compareTo(s2)); // 不同輸出字符差值-1System.out.println(s1.compareTo(s3)); // 相同輸出 0System.out.println(s1.compareTo(s4)); // 前k個字符完全相同,輸出長度差值 -3
}

4.?int compareToIgnoreCase(String str) 方法

與compareTo方式相同,但是忽略大小寫比較
public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("ac");String s3 = new String("ABc");String s4 = new String("abcdef");System.out.println(s1.compareToIgnoreCase(s2)); // 不同輸出字符差值-1System.out.println(s1.compareToIgnoreCase(s3)); // 相同輸出 0System.out.println(s1.compareToIgnoreCase(s4)); // 前k個字符完全相同,輸出長度差值 -3
}

5.易錯點(超級重點)

public static void main(String[] args) {String s1="hhh";String s2="hhh";System.out.println(s1==s2);//結果為true}

這時候因為s1和s2都是直接賦值,且內容一樣,這時編譯器會默認s1和s2指向同一塊空間。

3.String類的常用方法

3.1 字符串查找

下圖是一些Java中常用的字符串查找功能的方法。

2845c30522b04068b842a281a29d0e51.png

charAt(int index) 方法

用來查找字符串中指定位置上的字符

public class Test {public static void main(String[] args) {String str="manlebron";System.out.println(str.charAt(4));//輸出e}
}

以上代碼是查找字符串中下標為4的字符,是e。

int indexOf(int ch)方法

用來查找指定字符第一次出現的位置

public class Test {public static void main(String[] args) {String str="manlebron";System.out.println(str.indexOf('n'));}
}

int indexOf(int ch, int fromIndex)方法

用來在字符串中從fromIndex位置開始尋找第一次出現字符ch的位置

public class Test {public static void main(String[] args) {String str="manlebron";System.out.println(str.indexOf('l',2));}
}

int indexOf(String str)?方法

用來查找str第一次在字符串中出現的位置

public class Test {public static void main(String[] args) {String str="manlebron";System.out.println(str.indexOf("le"));}
}

由于剩下的方法用法差不多,就不 一 一 介紹了。

3.2 字符串轉換

1. 數值和字符串之間的轉換

public static void main(String[] args) {// 數字轉字符String s1 = String.valueOf(1234);String s2 = String.valueOf(12.34);String s3 = String.valueOf(true);String s4 = String.valueOf(new Student("Hanmeimei", 18));System.out.println(s1);System.out.println(s2);System.out.println(s3);System.out.println(s4);System.out.println("=================================");// 字符串轉數字// 注意:Integer、Double等是Java中的包裝類型,這個后面會講到int data1 = Integer.parseInt("1234");double data2 = Double.parseDouble("12.34");System.out.println(data1);System.out.println(data2);
}

2. 大小寫轉換

public static void main(String[] args) {String s1 = "hello";String s2 = "HELLO";// 小寫轉大寫System.out.println(s1.toUpperCase());// 大寫轉小寫System.out.println(s2.toLowerCase());
}

3.字符串和數組之間的轉換

public static void main(String[] args) {String s = "hello";// 字符串轉數組char[] ch = s.toCharArray();for (int i = 0; i < ch.length; i++) {System.out.print(ch[i]);}System.out.println();// 數組轉字符串String s2 = new String(ch);System.out.println(s2);}

4. 格式化

public static void main(String[] args) {String s = String.format("%d-%d-%d", 2019, 9,14);System.out.println(s);
}

d3d6fccd700f44d89e9e7fdb29399ea1.png

?4.字符串替換

用來將一個字符串替換原有字符串中指定的一部分。

2f45c374355345d98c7a6fa373fdc4b8.png

 public static void main(String[] args) {String str = "helloworld" ;System.out.println(str.replaceAll("l", "_"));System.out.println(str.replaceFirst("l", "_"));}

26a876d777d6496caae43d5c0ed83fcd.png

?5. 字符串拆分------split方法

用來將一個字符串按指定的分割符將原來的字符串分割成多個字符串。

718cf82b7ebf4a519d8100c1d5db4b24.png

public static void main(String[] args) {String str = "hello world hello bit" ;String[] result = str.split(" ") ; // 按照空格拆分for(String s: result) {System.out.println(s);}}

d5f31b3d88f84c198c1d197d14d83d5c.png

?部分拆分

public static void main(String[] args) {String str = "hello world hello bit" ;String[] result = str.split(" ",3) ; // 按照空格拆分,分為3組for(String s: result) {System.out.println(s);}}

8b531713651743a78e07924d61bf94dc.png

注意事項:拆分是常用的操作,一定要重點掌握。另外,有些特殊的字符無法直接進行拆分,需要加上轉移符號 ' \\?' 。

如拆分IP地址

?如以下代碼

public class Test {public static void main(String[] args) {String IP="192.168.1.1";String s[]=IP.split(".");for(String tmp:s){System.out.println(tmp);}}
}

運行代碼

3a7ee3781af24bc8809b663597134aac.png

5.1 特殊字符的拆分?

1.點字符

我們發現什么輸出都沒有,這也就意味這分割沒成功,因為 " . "是一個特殊的操作符,需要加上轉義符號 " \\ " 。

修改如下

public class Test {public static void main(String[] args) {String IP="192.168.1.1";String s[]=IP.split("\\.");  //在 " . " 前加\\for(String tmp:s){System.out.println(tmp);}}
}

運行代碼

baea70407e56426482cd13e3b292d940.png

?2. " \ " 字符

由于 \ 是一個整除符號,想要在表示 \ 是一個普通的斜桿,就必須在前面再加一個 \ 。

所以將其作為分割符時,要寫成 "\\\\".

public static void main(String[] args) {String str="haha\\man\\what\\can\\I\\say?";for(String tmp:str.split("\\\\")){System.out.println(tmp);}}

9cf27251af6c4ce680e48db73c83eed9.png

5.2?多次拆分

當一個字符串中有多個字符時,我們可以進行多次拆分。

public static void main(String[] args) {String IP="192&man.168.1.1&haha";String s[]=IP.split("\\.");  //在 " . " 前加\\for(String tmp:s){for(String tmp2:tmp.split("&")){System.out.println(tmp2);}}}

運行代碼:z

871d9e0ab3d54610bea27833cefdfd0c.png

我們也可以用 “ | ” 作為連字符,進行有多個字符的字符串進行拆分。

public static void main(String[] args) {String IP="192&man.168.1.1&haha";for(String tmp:IP.split("&|\\.")){System.out.println(tmp);}}

3c7b7106006547b58c924288a5d52d63.png

注意:不能在指定的分隔符前加上一個空格,因為空格也算一個字符。?

public static void main(String[] args) {String IP="192&man.168.1.1&haha";for(String tmp:IP.split("\\. | &")){System.out.println(tmp);}}

4e45573f3b13433d85e151861832f7f1.png

如上圖所示,在分隔符前加一個空格,效果就變得不一樣了。因為加了空格之后,分隔符就變成了“分隔符+空格”。

?5.3 小總結

1.字符?" | " , " * " , " + "都得加上轉義字符,前面加上 " \\ " 。

2.??而如果是??" \ " ,那么就得寫成 " \\\\ " 。

3.?如果一個字符串中有多個分隔符,可以用"|"作為連字符。

6. 字符串截取-----substring方法

1cebf5ee05d84e92aea9db21f1f94ae1.png

以上的substring方法是用來截取字符串中的一部分內容的。

代碼演示

public static void main(String[] args) {String str = "helloworld" ;System.out.println(str.substring(5));System.out.println(str.substring(0, 5));//左開右閉 [0,5)}

89d6992fd98d4005b4076e265302bf16.png

7.其他方法---trim( )方法

trim( ) 方法是用來除去字符串兩邊的空格的,但并不會出去字符串里面的空格。

代碼演示

public static void main(String[] args) {String str="    what can I say      ";String s=str.trim();System.out.println(s);}

a87728d3d2a84b209e8201ad7a3ce340.png

8. 字符串的不可變性

首先,我們要清楚,只要涉及到String類型的轉變都不是在原字符串上進行的修改,原理是產生一個新的對象。?

?1.string類在設計時就是被設計為無法改變的,在String類中已經具體描述了,如下圖:

638bc4671d634698aa2c4220f3779045.jpeg

64ae116509774a869d370285e03d7c9b.jpeg

從該圖中還可以看出,字符串的內容是保存在char[ ] value 數組中的。

String類是如何設計成無法改變的呢?

一直有人誤認為String類之所以無法被改變是因為String類被final修飾或者string類中的那個數組被final修飾,其實這些都是錯誤的。

因為一個類被final修飾只能表明這個類無法被繼承,一個數組被final修飾,表示數組名存的引用無法被改變。這些都與String類無法被改變有聯系。

真正的原因是,存放字符串的那個數組被private修飾了,且String類內沒有提供任何方法來讓外界去訪問和使用該數組,所以就造成了字符串的不可變性。

10.字符串的修改

注意:我們要盡量避開對字符串的直接修改,因為String類是無法被改變的,所有的修改都會創建新的對象,會導致效率非常底下。

如以下代碼:

public static void main(String[] args) {String s = "hello";s += " world";System.out.println(s); // 輸出:hello world}

這段代碼看似很簡單,有看起來像直接對String類進行了修改。其實不然,

在這段代碼的背后做了很多工作,先是創建了一個StringBuilder對象,在原來s中字符串的內容存到StringBuilder對象里面,然后在對StringBuilder對象進行了修改,然后再通過toString()方法轉換為String類型,最后再放回一個新的String類的對象。

如下圖

a4725defd9bd435ebf9cf06b1b1c59f9.jpeg

這里創建了很多臨時變量,就導致了效率低下。

因此我們要盡量避免對String類的直接改變,如果要修改建議盡量 使用StringBuffer或者StringBuilder。

11.StringBuilder和StringBuffer

由于String類型無法直接被改變,再Java中提供了StringBuilder和StringBuffer類,這兩個類也是可以存儲字符串的,但可以直接對字符串修改的。

public static void main(String[] args) {StringBuilder stringBuilder=new StringBuilder("haha ");System.out.println(stringBuilder.append("man"));StringBuffer stringBuffer=new StringBuffer("what can I say");stringBuffer.append("?");System.out.println(stringBuffer);}

e4eea03714af4b84b299daf7e96a6f78.png

其實?StringBuilder和StringBuffer的用法很相似,就一個區別。

ba97e3bcdcdd49abb92ae467b0b55ce3.png

如上圖StringBuffer中多了一個synchronized,這個可以理解為一把鎖,在多線程的情況下可以保證安全。

而StringBuilder主要是在單線程情況下使用。

StringBuilder和StringBuffer和String的區別

1.?String的內容不可修改,StringBuffer與StringBuilder的內容可以修改.

2.StringBuffer與StringBuilder大部分功能是相似的
3.StringBuffer采用同步處理,屬于線程安全操作;而StringBuilder未采用同步處理,屬于線程不安
全操作。

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

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

相關文章

溝通程序化(1):跟著鬼谷子學溝通—“飛箝”之術

溝通的基礎需要傾聽&#xff0c;但如果對方聽不進你的話&#xff0c;即便你說的再有道理&#xff0c;對方也很難入心。讓我們看看鬼谷子的“飛箝”之術能給我們帶來什么樣的啟發吧&#xff01; “飛箝”之術&#xff0c;源自中國古代兵法家、縱橫家鼻祖鬼谷子的智慧&#xff0…

SpringBootWeb 篇-深入了解 Spring 異常處理、事務管理和配置文件參數配置化、yml 配置文件

&#x1f525;博客主頁&#xff1a; 【小扳_-CSDN博客】 ?感謝大家點贊&#x1f44d;收藏?評論? 文章目錄 1.0 配置文件 1.1 yml 配置文件 1.2 參數配置化 1.2.1 使用 Value 注解注入單個配置參數 1.2.2 使用 ConfigurationProperties 注解將一組相關配置參數注入到一個類中…

discuz論壇怎么修改備案信息

大家好&#xff0c;今天給大家分享下discuz如何填寫備案信息并且展示在網站首頁。大家都知道國內網站都需要備案&#xff0c;不通過備案的網站上是沒辦法通過域名打開的。大家也可以通過搜索網創有方&#xff0c;或者直接點擊網創有方 查看懸掛備案號后的效果。 首先大家可以看…

如何在CentOS中合理劃分磁盤空間以優化系統性能

目錄 前言 理想的分區方案 為什么需要單獨分區 安全性 性能 管理和維護 穩定性和可靠性 升級和兼容性 結論 前言 在進行CentOS系統的安裝和配置時&#xff0c;合理劃分磁盤空間是確保系統性能、安全性和易于管理的關鍵步驟。本文將探討如何根據系統的硬件配置和預期用途…

安全測試掃描利器-Burpsuite

&#x1f525; 交流討論&#xff1a;歡迎加入我們一起學習&#xff01; &#x1f525; 資源分享&#xff1a;耗時200小時精選的「軟件測試」資料包 &#x1f525; 教程推薦&#xff1a;火遍全網的《軟件測試》教程 &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1…

vscode常用插件及插件安裝方式

一、常用插件 Chinese (Simplified) (簡體中文) Language Pack for Visual Studio Code 說明&#xff1a;中文語言包擴展&#xff08;簡體&#xff09; open in browser 說明&#xff1a;可以在默認瀏覽器或應用程序中打開當前文件 Auto Rename Tag 說明&#xff1a;自動重…

Linux 命令:awk

1. 寫在前面 本文主要介紹 Linux “awk” 命令&#xff1a;“awk” 是另一個強大的文本處理工具&#xff0c;用于處理和操作結構化數據&#xff0c;如日志文件和命令輸出。它可以根據需要為我們打印特定的列值。 公眾號&#xff1a; 滑翔的紙飛機 2. awk 命令 我們能用 awk 做…

Android 控件保持寬高比得幾種方式

文章目錄 Android 控件保持寬高比得幾種方式adjustViewBounds百分比布局ConstraintLayout自定義View Android 控件保持寬高比得幾種方式 adjustViewBounds 僅適用于 ImageView&#xff0c;保持橫豎比。 <ImageViewandroid:layout_width"match_parent"android:l…

動態規劃(Dynamic-Programming)問題講解

動態規劃類問題 從已知子問題的解&#xff0c;推導出當前問題的解 推導過程可以表達為一個數學公式用一維或二維數組來保存之前的計算結果&#xff08;可以進一步降維優化&#xff09; 將當前問題 分解成子問題 &#xff0c;找出遞歸公式&#xff0c;分階段進行求解 求解過程中…

vue3+ts封裝一個button組件

創建一個新的Button組件文件 Button.vue&#xff1a; <template><button :class"buttonClass" :disabled"disabled" click"handleClick"><slot></slot><i v-if"icon" :class"icon"></i&g…

python 生成器yield

生成器 創建生成器的方式 生成器推導式yield關鍵字 生成器相關方法 for&#xff1a;循環遍歷生成器中的每一個值next&#xff1a;獲取生成器中的下一個值 生成器注意點 代碼執行到yield會暫停&#xff0c;然后把結果返回出去&#xff0c;下次啟動生成器會在暫停的位置繼續執行…

進程間通信(27000字超詳解)

&#x1f30e;進程間通信 文章目錄&#xff1a; 進程間通信 進程間通信簡介 ??????進程間通信目的 ??????初識進程間通信 ??????進程間通信的分類 匿名管道通信 ??????認識管道 ??????匿名管道 ??????匿名管道測試 ??????管道的四種…

第十五課,海龜畫圖:抬筆與落筆函數、畫曲線函數

一&#xff0c;turtle.penup()和turtle.pendown()&#xff1a;抬起與落下畫筆函數 當使用上節課學習的這個turtle.forward()&#xff1a;畫筆前進函數時&#xff0c;畫筆會朝著當前方向在畫布上留下一條指定&#xff08;像素&#xff09;長度的直線&#xff0c;但你可能發現&a…

Map Python用法:深度解析與應用探索

Map Python用法&#xff1a;深度解析與應用探索 在Python編程中&#xff0c;map() 函數是一種強大的內置高階函數&#xff0c;用于對可迭代對象中的每個元素應用指定的函數&#xff0c;并返回一個新的迭代器&#xff0c;其中包含函數應用后的結果。本文將從四個方面、五個方面…

Bean的生命周期中有哪些對外開放的接口,及各種作用

Bean的生命周期中有哪些對外開放的接口&#xff0c;及各種作用 在 Spring 框架中&#xff0c;Bean 的生命周期可以通過一系列的回調接口來管理和控制。以下是 Spring 中對外開放的主要 Bean 生命周期接口以及它們的作用&#xff1a; InitializingBean 和 DisposableBean 接口&…

C++|set、map模擬實現<——紅黑樹

目錄 一、紅黑樹的迭代器 1.1紅黑樹迭代器框架 1.2operator*() && operator->() 1.3operator() 1.4operator--() 1.5operator() && operator!() 1.6begin() && end() 二、如何用紅黑樹搭配map和set(仿函數) 三、紅黑樹封裝map和set(簡易版…

springboot + Vue前后端項目(第十三記)

項目實戰第十三記 寫在前面1.建立角色表2. 后端代碼生成2.1 RoleController 3. 前端頁面的搭建3.1 Role.vue3.2 路由3.3 Aside.vue3.4 頁面效果 4.建立菜單表5.后端代碼編寫5.1 Menu5.2 MenuController 6.前端頁面的搭建6.1 Menu.vue6.2 路由6.3 Aside.vue6.4 頁面效果 總結寫在…

keepalived安裝文檔

目錄 1、安裝環境 2、安裝keepalived 2.1 上傳keepalived安裝文件 2.2 解壓 2.3 安裝keepalived 2.4 加入開機啟動&#xff1a; 2.5 配置日志文件 2.6 打開防火墻的通訊地址 1、安裝環境 su - root yum -y install kernel-devel* yum -y install openssl-* yum -y …

vx小程序初學

小程序初學 在我還沒接觸到微信小程序之前&#xff0c;通常使用輪播要么手寫或使用swiper插件去實現&#xff0c;當我接觸到微信小程序之后&#xff0c;我看到了微信小程序的強大之處&#xff0c;讓我為大家介紹一下吧&#xff01; swiper與swiper-item一起使用可以做輪播圖 …

把自己的服務器添加到presearch節點

Presearch is a scam. Before, judging by the price of the token you should have been able to get between $150-$200 after 12-13 months of regular searches. "If you use this service for the next 11 years you will have earned $30!" Presearch大約需要…