在任何編程語言中祥楣,要執(zhí)行任何類型的計(jì)算,您總是使用數(shù)值(Int汉柒、float误褪、double 等)、布爾和字符串類型的數(shù)據(jù)碾褂。據(jù)說它們是核心或原始數(shù)據(jù)類型兽间,您甚至需要?jiǎng)?chuàng)建復(fù)雜的結(jié)構(gòu)/類,并且詳細(xì)了解這些總是有助于您設(shè)計(jì)更好的代碼斋扰,并選擇正確的數(shù)據(jù)組合以從您的函數(shù)/程序中獲得準(zhǔn)確的輸出.
在本文中渡八,我們將深入探討字符串的概念啃洋。了解它們?cè)?Java 中是如何工作的传货,以及您可以對(duì)它們執(zhí)行的所有操作,因此無需任何費(fèi)用宏娄,讓我們開始吧问裕!
java中的字符串是什么?
字符串孵坚?你首先想到的問題是它們是什么粮宛?它們長(zhǎng)什么樣?他們的回答非常簡(jiǎn)單卖宠,就像在我們的英語語法中一樣巍杈,字符串只不過是集合,是一些字符(字母和符號(hào))放在一起扛伍。它不是一個(gè)你有意義或沒有意義的字符串筷畦,直到是一組字符,它是一個(gè)字符串刺洒。例如“This is a sample String”鳖宾,甚至“zxczxvc adsad qwe”也是一個(gè)字符串。
不同的編程語言有不同的表示字符串的方式逆航,例如有些表示為'hello world'或“hello world”鼎文,需要注意的是字符串可以以單引號(hào)-'或雙引號(hào)-“”開頭。同樣通過語言設(shè)計(jì)因俐,語言有可能不直接支持字符串類型拇惋,它們可能支持字符作為原始類型周偎,并且可以通過這些字符的組合形成字符串。如果語言支持字符類型撑帖,則字符始終以單引號(hào)開頭栏饮,而字符串將以雙引號(hào)開頭。
無論如何磷仰,背景已經(jīng)足夠了袍嬉,回到我們?cè)谶@里學(xué)習(xí)的語言是 TADA ...... Java,這里的 String 不是原始數(shù)據(jù)類型灶平,即使它包含在語言中伺通。Java 支持字符類型,即逢享。char
數(shù)據(jù)類型罐监。讓我們看看它的例子:
字符類型示例:
char thisIsa = 'a';
char thisIsA = 'A';
只是為了你的信息thisIsa
不等于thisIsA
。有很多關(guān)于角色的知識(shí)我們不會(huì)深入研究(您可以從這里了解更多關(guān)于它們的信息 → chetangupta.net)瞒爬。
字符串類型示例:
String thisIsA = "A";
String thisIsa = "a";
同樣去那里thisIsa
不等于thisIsA
弓柱,因?yàn)樽址菂^(qū)分大小寫的。希望您現(xiàn)在了解有關(guān)字符串的要點(diǎn)和背景……
如果是這樣侧但,給我解謎矢空?
char thisIsA = 'A';
String thisIsAlsoA = "A";
既然我們說字符串是字符序列的集合,那么字符串變量thisIsAlsoA
是否等于thisIsA
禀横?如果你好奇地想屁药,如果你直到文章結(jié)尾都找不到棒子……
如何創(chuàng)建字符串對(duì)象?
讓我們深入了解 Java 中的字符串創(chuàng)建過程柏锄。我們使用雙引號(hào)創(chuàng)建 String 的方式稱為創(chuàng)建String Literal
酿箭。
例子 :
String a = "A";
String greet = "Hello World!";
String pokemon = "Pikachu";
創(chuàng)建它的其他方法是 using String Object
,因?yàn)槲覀冎涝?Java 中創(chuàng)建對(duì)象是使用new
運(yùn)算符完成的趾娃,因此我們將創(chuàng)建類似的字符串String apple = new String(``"``apple``"``);
更多示例:
String a = new String("A");
String greet = new String("Hello World!");
String pokemon = new String("Pikachu");
你可能會(huì)想有什么區(qū)別缭嫡?還有為什么我應(yīng)該使用 Object 方法創(chuàng)建它,看起來更冗長(zhǎng)抬闷?好吧妇蛀,您需要了解 Java 內(nèi)存模型的幕后實(shí)際發(fā)生了什么。
當(dāng)我們創(chuàng)建 String Literal 時(shí)饶氏,JVM 會(huì)在 String Pool 中查找相同的值是否已經(jīng)存在讥耗。如果找到,它將返回對(duì)象引用疹启,如果沒有古程,則創(chuàng)建具有給定值的新字符串對(duì)象并存儲(chǔ)在字符串池中。
PS:要了解更多關(guān)于字符串池結(jié)帳chetangupta.net喊崖。
而當(dāng)我們使用new
運(yùn)算符創(chuàng)建對(duì)象時(shí)挣磨,會(huì)發(fā)生兩件事雇逞,我們傳遞的字符串值會(huì)檢查并放入字符串池中,但字符串的對(duì)象是創(chuàng)建到堆內(nèi)存中的茁裙。因此這個(gè)方法需要更長(zhǎng)的時(shí)間來執(zhí)行塘砸,另一方面要記住的是它每次都會(huì)構(gòu)造一個(gè)新對(duì)象。
好的晤锥,知道這個(gè)背景很好掉蔬,但它如何解釋new
操作員用例?讓我們理解:
字符串文字是字符串對(duì)象矾瘾,但字符串對(duì)象并不總是字符串文字女轿。字面量也表示固定值,即常量壕翩,這意味著字符串字面量一旦創(chuàng)建就不能修改蛉迹,因此通常說 Java 字符串是不可變的。稍后我們將詳細(xì)討論它們放妈。但是 String Object 不同北救,它被設(shè)計(jì)為可以變異的。
因此芜抒,每當(dāng)我們處理需要大量更新的字符串時(shí)珍策,我們會(huì)更喜歡字符串對(duì)象而不是字符串文字。
總是喜歡使用StringBuffers
或StringBuilders
制作需要大量修改的字符串對(duì)象挽绩。因?yàn)?code>StringBuilders它們比 StringBuffers 更現(xiàn)代并且具有更多功能膛壹。
例子 :
StringBuilder greetBuilder = new StringBuilder("");
greetBuilder.append("hello");
greetBuilder.append(" ");
greetBuilder.append("World");
greetBuilder.append("!");
String greet = greetBuilder.toString();
System.out.println(greet) // output : hello World!
希望您現(xiàn)在了解字符串對(duì)象與字符串文字的作用。
字符串操作和方法:
現(xiàn)在有趣的部分來了唉堪,讓我們探索一下我們可以對(duì) String 數(shù)據(jù)類型執(zhí)行哪些可能的操作:
字符串長(zhǎng)度:
如果您想知道字符串的長(zhǎng)度,即字符串中的字符總數(shù)肩民,請(qǐng)使用函數(shù)length()
而不是字符串示例:
String apple = "Apple";
println(apple.length()); // output --> 5
Character at Index :
由于 String 是一個(gè)字符序列唠亚,我們可以根據(jù)給定的索引獲取字符。所以我們可以使用索引獲取字符charAt(index)
例子 :
// if we want to get `l` from string apple then
String apple = "Apple";
println(apple.charAt(3)); // output --> `l`
注意:請(qǐng)理解字符串是不可變的持痰,即您可以讀取索引處的值但不能更新給定索引上的值灶搜,即setCharAt(index)
字符串上沒有類似的函數(shù)。
字符串的連接/添加:
我們可以使用函數(shù)將兩個(gè)字符串(也稱為連接)添加到單個(gè)字符串中concat()
工窍。注意:我們操作后得到的新連接字符串將是新字符串割卖,因?yàn)樽址遣豢勺兊摹?/p>
例子 :
String apple = "Apple";
String orange = "Orange";
println(apple.concat(orange)); // output --> AppleOrange
println(orange.concat(apple)); // output --> OrangeApple
子字符串:
子字符串意味著根據(jù)給定的索引獲取字符串的一部分。為此有兩種重載函數(shù)方法:
-
subString(int startIndex) : String
:它將返回從開始索引到字符串結(jié)尾的字符串 -
subString(int startIndex, int endIndex):String
:它將返回從開始索引到結(jié)束索引的字符串
例子 :
String orange = "Orange";
println(orange.substring(/*StartIndex*/4)); // output --> ge
println(orange.substring(/*StartIndex*/1,/*EndIndex*/5)); // output --> rang
包含:
我們使用 Contains 來檢查 String 是否包含另一個(gè)字符串患雏。注意:在后臺(tái)它檢查 CharSequence 以獲得比檢查每個(gè)單詞更快的評(píng)估鹏溯。(從這里了解更多信息:chetangupta.net。
例子 :
String orange = "Orange";
println(orange.contains("range")); // output --> true
println(orange.contains("apple")); // output --> false
加入字符串:
Join 顧名思義淹仑,它將連接兩個(gè)字符串丙挽,但您可能想知道 join 和 concat 之間有什么區(qū)別肺孵?
- 只需查看他們收到的參數(shù),對(duì)于 Join颜阐,您可以為字符串傳輸 'n' 數(shù)字平窘,但對(duì)于 concat 它只能使用兩個(gè)字符串,
- 加入作為提供分隔符/分隔符的能力凳怨,即在合并字符串時(shí)使用的符號(hào)瑰艘。
- 與 concat 不同,Join 是 String 類的靜態(tài)函數(shù)肤舞。
例子 :
String apple = "Apple";
String orange = "Orange";
String berry = "StrawBerries";
String seperator = "|";
println(String.join(seperator,apple,orange,berry));
// output --> Apple|Orange|StrawBerries
與字符串比較:
只是為了讓您知道磅叛,當(dāng)我們執(zhí)行比較操作時(shí),我們會(huì)審查兩個(gè)項(xiàng)目是否相等萨赁,第一個(gè)項(xiàng)目大于(>)第二個(gè)項(xiàng)目或第一個(gè)項(xiàng)目小于(<)第二個(gè)項(xiàng)目弊琴。
在編程中,比較函數(shù)返回整數(shù)值來表示相同的場(chǎng)景杖爽。
if item1 == item2 then returns 0,
if item1 > item2 then returns 1,
if item1 < item2 then returns -1,
在字符串中敲董,這些比較是基于字典(字典順序)的,即
if string1 == string2 then returns 0
if string1 > string2 then returns 1, (string 1 comes ahead in dictinoary order)
if string1 < string2 then returns -1, (string 2 comes ahead in dictinoary order)
在 Java 中慰安,我們有兩個(gè)函數(shù)用于比較 Java 中的字符串腋寨。
-
compareTo()
:這比較兩個(gè)字符串,但區(qū)分大小寫化焕。 -
compareToIgnoreCase()
:這比較兩個(gè)字符串萄窜,但不區(qū)分大小寫。
讓我們看看例子:
// case sensitive comparison
String apple = "Apple";
println(apple.compareTo("Apple")); // output --> 0
println(apple.compareTo("apple")); // output --> -32
// case in-sensitive comparison
String apple = "Apple";
println(apple.compareToIgnoreCase("Apple")); // output --> 0
println(apple.compareToIgnoreCase("apple")); // output --> 0
字符串中的大小寫:
我們可以使用兩個(gè)函數(shù)來控制字符串字符的大小寫:
-
toUpperCase()
:此函數(shù)將輸出字符串中的所有字符大寫撒桨, -
toLowerCase()
:類似地查刻,這個(gè)函數(shù)將輸出字符串中的所有字符小寫。
String apple = "ApPlE";
println(apple); // output --> ApPlE
println(apple.toUpperCase()); // output --> APPLE
println(apple.toLowerCase()); // output --> apple
剝離空白:
字符串值通撤锢啵可以從開頭或結(jié)尾包含空格穗泵。注意:字符之間的空格不是空格。我們可以使用trim()
函數(shù)來刪除它們谜疤。
String appleTrimmed = " apple ".trim();
println(appleTrimmed) // output --> apple
println(appleTrimmed.length()) // output --> 5
替換字符串中的字符:
如果要將字符從舊字符替換為新字符佃延。
注意:請(qǐng)記住,替換字符是字符串與在字符串中的某個(gè)索引處設(shè)置字符的過程不同夷磕。字符串不可變的規(guī)則也將應(yīng)用在那里履肃,因此當(dāng)您嘗試替換字符時(shí),您會(huì)得到一個(gè)帶有替換字符的全新字符串坐桩。
例子 :
String apple = "apple";
println(apple.replace("a","pinea")); // output --> pineapple
使用“+”運(yùn)算符進(jìn)行字符串連接
我們已經(jīng)看到了連接兩個(gè)字符串的兩種方法尺棋,一種是 concat,另一種是 join撕攒,但是你會(huì)遇到一個(gè)非常常見的連接兩個(gè)字符串的模式是“+”陡鹃。
使用“+”運(yùn)算符與 concat 函數(shù)的工作方式非常相似烘浦。例子 :
String apple = "apple";
String orange = "Orange";
String berry = "StrawBerries";
println(apple.concat(orange).concat(berry)); // output --> appleOrangeStrawBerries
println(apple + orange + berry); // output --> appleOrangeStrawBerries
我們應(yīng)該使用哪一個(gè)?
在我們看來萍鲸,比較“concat()”和“+”闷叉,“+”運(yùn)算符似乎更具可讀性,但在數(shù)字類型數(shù)據(jù)中使用時(shí)要小心脊阴。
例子 :
int orangeCount = 5;
int berryCount = 5;
println("fruits count:" + orangeCount + berryCount);
// wrong output --> fruits count:55
println("fruits count:" + (orangeCount + berryCount));
// right output --> fruits count:10
但正如我們建議的與 concat 相同的問題握侧,由于字符串是不可變的,我們基本上創(chuàng)建新字符串更好更快的方法是使用 StringBuilder嘿期。
創(chuàng)建格式字符串
我們已經(jīng)介紹了字符串的許多核心功能品擎,并且我們可以清楚地看到一個(gè)用例,在該用例中备徐,我們將字符串附加到字符串萄传、浮點(diǎn)數(shù)、數(shù)字等……如果我們可以在字符串中包含占位符值蜜猾,并且在運(yùn)行時(shí)這些占位符會(huì)怎么樣可以替換為我們想要輸入的值嗎秀菱?
這就是String.format()
函數(shù)的作用。我們使用占位符/說明符創(chuàng)建一個(gè)字符串蹭睡,并用值填充它們衍菱,我們也將這種類型的字符串稱為模板字符串。
我們對(duì)不同類型的數(shù)據(jù)類型使用不同的說明符肩豁,最常用的一次是:
- %b 為布爾值脊串,
- %s 用于字符串,
- %d 僅用于整數(shù)數(shù)字
- %f 用于浮點(diǎn)數(shù)
還有其他的清钥,您可以從這里閱讀更多內(nèi)容:chetangupta.net
例子 :
println(String.format("%s has %d apple, and %d oranges", "John Doe", 3, 2));
// output --> John Doe has 3 apple, and 2 oranges
注意:值根據(jù)它們?cè)诤瘮?shù)參數(shù)中的出現(xiàn)被放置到模板位置琼锋,
與 concat 或 plus 運(yùn)算符相比,此方法在處理非常長(zhǎng)的字符串時(shí)很有用循捺。性能方面它不如 StringBuilder 好斩例,因?yàn)樗枰谏勺址敖馕稣麄€(gè)字符串和參數(shù)。
字符串中的轉(zhuǎn)義字符
當(dāng)我們使用長(zhǎng)字符串時(shí),如果我們嘗試將其分成兩部分毁欣,您最容易想到的就是按 Enter 并在下一行繼續(xù)使用您的字符串籍凝,但如果您嘗試這樣做,編譯器將處理你語法錯(cuò)誤狰右,例如:
String message = "
I want to make
very lengthy String!
";
要執(zhí)行這些功能,您需要在字符串中使用特殊字符來\n
在字符串中添加新行。
String message = "\nI want to make\nvery lengthy String!";
/*
* Output :
* I want to make
* very lengthy String!
*/
轉(zhuǎn)義字符:
\t → add horizontal tab
\n → add new line
\’ → add single quotes in String
\” → add double quotes in String
\\ → add backslash in the String
例子 :
String message = "Hello\tWorld!";
println(message); // output --> Hello World!
message = "Hello\nWorld!";
println(message);
/*
* Output -->
* Hello
* World!
*/
message = "Hello\'World\'!";
println(message); // output --> Hello'World'!
message = "Hello\"World!\"";
println(message); // output --> Hello"World!"
message = "Hello\\World!\\";
println(message); // output --> Hello\World!\
Java 字符串是不可變的
如果您通讀整篇文章踩萎,您就會(huì)一次又一次地重復(fù)這句話。這是因?yàn)樗?Java 字符串發(fā)揮作用的主要機(jī)制很钓。
將 String 設(shè)置為不可變的關(guān)鍵原因是具有緩存香府、性能和安全性的好處董栽。
String 是任何程序中使用最廣泛的數(shù)據(jù)結(jié)構(gòu),JVM 通過在 String 池中僅存儲(chǔ)每個(gè) String 的一個(gè)副本來優(yōu)化為它們分配的內(nèi)存量企孩。
因此緩存字符串文字并重用它們可以節(jié)省大量堆空間锭碳,因?yàn)椴煌淖址兞恳米址刂械耐粋€(gè)對(duì)象,從而節(jié)省了關(guān)鍵的內(nèi)存資源并提高了應(yīng)用程序的性能勿璃。
String 不可變的另一個(gè)優(yōu)點(diǎn)是它們是線程安全的擒抛,因此并發(fā)環(huán)境中的 String 可以安全地讀取和更新。
獎(jiǎng)勵(lì):謎語解決方案
char thisIsA = 'A';
String thisIsAlsoA = "A";
isthisIsAlsoA
等于thisIsA
? 這是我們問的謎語补疑。
如果您認(rèn)為是歧沪,那么對(duì)不起,伙計(jì)莲组!您錯(cuò)了诊胞。從概念上講你是對(duì)的,這應(yīng)該是正確的锹杈,但問題是 Java 不是動(dòng)態(tài)類型的語言撵孤,它是靜態(tài)類型的。因此類型在這里扮演著重要的角色嬉橙。由于 String 和 char 的類型不匹配早直,因此失敗。它不會(huì)在 JavaScript 這樣的語言中失敗市框。
還有一件事...... String 是 char 的集合霞扬,對(duì)吧?枫振,因此我們可以使用 將我們的 String 轉(zhuǎn)換為 Character Array toCharArray()
喻圃,因?yàn)?Array 是一個(gè)集合,因此以編程方式證明我們的語句是正確的粪滤,如果我們將數(shù)組的第一個(gè)索引位置與字符進(jìn)行比較斧拍,它將是相等的. 好的 !
結(jié)論
讓我們回顧一下:
- 我們了解到字符串是字符序列的集合
- 在 Java 中杖小,我們可以通過兩種方式創(chuàng)建字符串 - 字符串字面量和字符串對(duì)象
- 我們可以對(duì)字符串執(zhí)行各種操作 - 連接肆汹、長(zhǎng)度、比較等等
- 什么是字符串中的特殊轉(zhuǎn)義字符
- 最重要的是為什么 String 是不可變的予权!
我們希望您學(xué)到了很多昂勉,并解開了圍繞 Java String 的所有奧秘和疑慮。
文章來源:https://ch8n.hashnode.dev/untangle-your-strings-in-java-cl36y41xp02wgmgnv0ym83yi8