java 字符串詳解

字符串(String)是一系列的字符(char)。例如“Hello”是5個(gè)字符书闸。字符串是一個(gè)不可變的對(duì)象尼变,也就是說(shuō)一旦創(chuàng)建就不能被修改。

字符串的創(chuàng)建

字符串創(chuàng)建有兩種方式:

  • 字符串字面量 String str1 = "Welcome";

    字符串是對(duì)象浆劲,雖然我們?cè)谶@里沒(méi)有用new創(chuàng)建對(duì)象嫌术,其實(shí)是編譯器給我們做了這些操作。這種創(chuàng)建的字符串對(duì)象有一個(gè)特點(diǎn)牌借,如果同樣的對(duì)象如果存在了蛉威,就不會(huì)創(chuàng)建一個(gè)新的對(duì)象,而是指向了同樣的對(duì)象走哺。例如String str2 = "Welcome";蚯嫌,則str1和str2是指向了字符串池中同樣的內(nèi)存地址。

  • new創(chuàng)建字符串 String str1 = new String("Welcome");
    用new關(guān)鍵字創(chuàng)建的字符串每次都會(huì)創(chuàng)建一個(gè)新的對(duì)象丙躏。

字符串池

注意點(diǎn):String str = new String("World"); 會(huì)產(chǎn)生幾個(gè)對(duì)象择示? 如果字符串池里面沒(méi)有“World”對(duì)象,會(huì)在字符串池里面生成一個(gè)對(duì)象晒旅,然后再生成一個(gè)字符串對(duì)象栅盲,str指向這個(gè)對(duì)象;如果字符串池里面已經(jīng)有了“World”對(duì)象废恋,則只會(huì)生成一個(gè)對(duì)象谈秫,str指向這個(gè)對(duì)象。

String常用方法

字符串某個(gè)位置的字符 charAt(int index)

參數(shù)的索引從0開(kāi)始鱼鼓,到str.length() - 1 為止拟烫。 如果不在這個(gè)范圍則會(huì)拋出IndexOutOfBoundsException異常。

String str = "Hello world!";
str.charAt(0);  // H
str.charAt(1);  // e

字符串是否相等比較 == && equals(Object obj) && equalsIgnoreCase(String string)

==是內(nèi)存的地址的比較迄本;equals首先會(huì)用==比較硕淑,比較區(qū)分字符串的大小寫(xiě),equalsIgnoreCase也會(huì)先用會(huì)用==比較,但是不區(qū)分大小寫(xiě)嘉赎。

String str1 = "Hello world!";
String str2 = "Hello World!";

System.out.println(str1 == str2); // false
System.out.println(str1.equal(str2)); // false
System.out.println(str1. equalsIgnoreCase(str2)); // false

字符串大小比較 compareTo(String string): && compareToIgnoreCase(String string)

compareTo會(huì)用每個(gè)字符的Unicode進(jìn)行比較置媳,如果第一個(gè)字符串比第二個(gè)字符串大就返回正數(shù),否則返回負(fù)數(shù)公条,如果一樣則返回0拇囊。

String str1 = "Hello world!";
String str2 = "Hello World!";

System.out.println(str1.compareTo(str2)); // w比W的Unicode編碼大32 結(jié)果為32
System.out.println(str1.compareToIgnoreCase(str2)); // 不區(qū)分大小寫(xiě)則相等,結(jié)果為0

字符串的前綴 startsWith(String prefix) 子字符串的前綴 startsWith(String prefix, int offset)

String str = "Hello world!";
System.out.println(str.startsWith("Hello"));  // 子字符串(Hello world!)的前綴是(Hello) ---> true
System.out.println(str.startsWith("wor", 6)); // 子字符串(world!)的前綴是(wor) ---> true 

字符串的后綴 endsWith(String suffix)

String str = "Hello world!";
System.out.println(str.endsWith("world!"));  // 子字符串(Hello world!)的后綴是(world!) ---> true

是否含有某個(gè)字符串 contains(CharSequence s)

String str = "Hello world!";
System.out.println(str.contains("a")); // false

字符出現(xiàn)的位置 indexOf(int ch) && indexOf(int ch, int fromIndex) && lastIndexOf(int ch) && lastIndexOf(int ch, int fromIndex)

如果找到返回索引位置靶橱,沒(méi)找到返回-1.

String str = "Hello world!";
        
// 從前完后找字符的位置
System.out.println(str.indexOf("o"));  // 4
System.out.println(str.indexOf("O"));  // -1
        
// 從某個(gè)位置開(kāi)始從前往后找字符的位置
// 注意:需要注意索引依然是從字符串的0開(kāi)始寥袭,不是從開(kāi)始檢索的位置開(kāi)始
System.out.println(str.indexOf("o", 6)); // 7
        
// 從后往前找字符串的位置
System.out.println(str.lastIndexOf("o")); // 7
        
// 從某個(gè)索引位置開(kāi)始從后往前找字符的位置
System.out.println(str.lastIndexOf("o", 6)); // 4

字符串出現(xiàn)的位置 indexOf(String str) && lastindexOf(String str)

String str = "Hello world!";
        
System.out.println(str.indexOf("llo"));     // 2
System.out.println(str.lastIndexOf("wor")); // 6

子串 substring(int beginIndex) && substring(int beginIndex, int endIndex)

beginIndex 不能小于0奢米,endIndex不能大于最大索引值。且beginIndex必須小于等于endIndex纠永。

String str = "Hello world!";
        
System.out.println(str.substring(6));    // 從索引6開(kāi)始到最后 ---> world!
System.out.println(str.substring(6, 6)); // 從索引6開(kāi)始到索引9 ---> wor

字符串拼接一 concat(String str)

System.out.println("Hello".concat(" ").concat("world!")); // Hello world!

字符串拼接二 join(CharSequence delimiter, CharSequence... elements)

這是一個(gè)靜態(tài)方法,第一參數(shù)是分隔符谒拴,后面是多個(gè)字符串尝江,用分隔符拼接起來(lái)

String str = String.join(" ", "This", "is", "a", "String"); // This is a String

字符的替換 replace(char oldChar, char newChar) && replace(CharSequence target, CharSequence replacement)

String str = "Hello world!";
// 把字符串中某個(gè)字符都替換成新的字符。
System.out.println(str.replace("o", "a")); // Hella warld!
// 把字符串中某個(gè)字符串都替換成新的字符串英上。
System.out.println(str.replace("llo", "")); // He world!

正則表達(dá)式的替換 replaceFirst(String regex, String replacement) && replaceAll(String regex, String replacement)

replaceAll 和 replaceFirst都是用正則表達(dá)式去匹配替換的炭序;replace是直接字符串替換

String str = "Telephone is 15512345678";
System.out.println(str.replaceFirst("\\d", "*")); // Telephone is *5512345678
System.out.println(str.replaceAll("\\d", "*"));   // Telephone is ***********

大寫(xiě) toUpperCase() && 小寫(xiě) toLowerCase()

String str = "Hello world!";
        
System.out.println(str.toUpperCase()); // HELLO WORLD!
System.out.println(str.toLowerCase()); // hello world!

字符串復(fù)用和初始化 intern()

String str1 = "Hello world!"; // 此時(shí)或在字符串池中建立一個(gè)"Hello world!"字符串
String str2 = new String("Hello world!").intern();  // 先在字符串池找"Hello world!",找到就賦值給str2苍日,沒(méi)有找到就初始化一個(gè)新的賦值給str2
System.out.println(str1.equals(str2)); // 相同

是否是空字符串

String str = "";
System.out.println(str.isEmpty()); // true

字符串拆分 split(String regex, int limit) && split(String regex)

split的第一個(gè)參數(shù)regex是一個(gè)正則表達(dá)式惭聂,第二個(gè)參數(shù)是返回分割的子字符串的最大值。默認(rèn)是傳0相恃,就是不限制個(gè)數(shù)辜纲,所有子字符串都返回。

String str = "2018/01/01";
        
String[] array = str.split("/");
for(int i = 0; i < array.length; i++) {
    System.out.println(array[i]); // 2018  01  01
}

字符串格式化 format(String format, Object... args)

String str1 = "Welcome";
String str2 = "Johnny";

// %1$s 代表參數(shù)1拦耐,%2$s 代表參數(shù)二耕腾,以此類推。杀糯。扫俺。
String formateStr = String.format("Format String is: %1$s and %1$s, %2$s", str1, str2);
System.out.println(formateStr);  // Format String is: Welcome and Welcome, Johnny
        
String formateStr2 = String.format("My String is %.6f", 12.12);
System.out.println(formateStr2); // My String is 12.120000

去掉收尾空格

String str = "  Welcome  ";
System.out.println(str.trim()); //Welcome 去掉了首位的空格

生成字符數(shù)組 char[] toCharArray()

String str = "Welcome";
char[] arr = str.toCharArray(); // ["W","e","l","c","o","m","e"]

根據(jù)字符數(shù)組生成字符串 copyValueOf(char[] data) && copyValueOf(char[] data, int offset, int count)

char[] data = {'a','b','c','d','e','f','g','h','i','j','k'};
String str1 = "Original1";
String str2 = "Original2";
        
str1 = str1.copyValueOf(data); // 取所有的數(shù)組元素
System.out.println("str1 after copy: " + str1); // str1 after copy: abcdefghijk
        
str2 = str2.copyValueOf(data, 5, 3); //從第5個(gè)索引開(kāi)始,取3個(gè)數(shù)組元素
System.out.println("str2 after copy: " + str2); // str2 after copy: fgh

把其他的類型數(shù)據(jù)變成字符串 valueOf() 或者用構(gòu)造函數(shù)new String()

public static String valueOf(boolean b): Used for converting boolean value to a String

public static String valueOf(char c): char to String

public static String valueOf(int i): int to String

public static String valueOf(long l): long to String

public static String valueOf(float f): float to String

public static String valueOf(double d): double to String

int i = 10; //int類型
float f = 10.10f; //float類型
long l = 111L; //long類型
double d = 2222.22; //double類型
char ch = 'A'; //char類型
char array[] = {'a', 'b', 'c'}; //char數(shù)組類型

//把int變成字符串
String str1 = String.valueOf(i); 
        
//把float變成字符串
String str2 = String.valueOf(f); 
        
//把long變成字符串g
String str3 = String.valueOf(l);
        
//把double變成字符串
String str4 = String.valueOf(d);
        
//把char變成字符串
String str5 = String.valueOf(ch);
        
//把char array變成字符串
String str6 = String.valueOf(array);

把字符串變成比特?cái)?shù)組 byte[] getBytes()

String擴(kuò)展

String && StringBuffer && StringBuilder

StringBuffer 和 StringBuilder 都可以認(rèn)為是可變的字符串固翰。但是他們之間有一個(gè)區(qū)別就是 StringBuffer 是線程安全的而StringBuilder不是線程安全的狼纬。所以如果多線程操作需要用StringBuffer,而單線程操作建議使用StringBuilder骂际,因?yàn)樗咝А?/p>

String 與 StringBuffer 和 StringBuilder 的區(qū)別是 不可變疗琉。

StringBuilder builder = new StringBuilder("Hello ");
builder.append("World!");
System.out.println(builder.toString()); // Hello world!

字符串轉(zhuǎn)成int Integer.parseInt() && Integer.valueOf()

需要保證字符串能轉(zhuǎn)成整形,否則會(huì)拋出NumberFormatException異常歉铝。

System.out.println(Integer.parseInt("22"));
System.out.println(Integer.valueOf("22"));

int轉(zhuǎn)成字符串 Integer.toString() && valueof() && format()

Integer.toString(22)

字符串轉(zhuǎn)成dobule Double.parseDouble(String) && Double.valueOf(String)

需要保證字符串能轉(zhuǎn)成dobule没炒,否則會(huì)拋出NumberFormatException異常。

System.out.println(Double.parseDouble("22.22"));
System.out.println(Double.valueOf("22.22"));

dobule轉(zhuǎn)成字符串 Double.toString() && valueof() && format()

Double.toString(22.22); 

字符串轉(zhuǎn)成long Long.parseLong() && Long.valueOf(String)

System.out.println(Long.parseLong("22"));
System.out.println(Long.parseLong("22"));

long轉(zhuǎn)成 字符串 Long.toString() && valueof() && format()

Long.toString(200)

字符串轉(zhuǎn)成Boolean Boolean valueOf(String s)

Boolean bobj = Boolean.valueOf("false");

Boolean轉(zhuǎn)成字符串 Boolean.toString(boolean b) && String.valueOf(boolean b) && format()

String str = Boolean.toString(false);

Date 和 String的相互轉(zhuǎn)換

DateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        
String dateString = "02-04-2018 23:30:00";
Date todaysDate = new Date();
        
try {
    // 把字符串變成日期
    System.out.println(format.parse(dateString));
    // 把日期變成字符串
    System.out.println(format.format(todaysDate));
            
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末犯戏,一起剝皮案震驚了整個(gè)濱河市送火,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌先匪,老刑警劉巖种吸,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異呀非,居然都是意外死亡坚俗,警方通過(guò)查閱死者的電腦和手機(jī)镜盯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)猖败,“玉大人速缆,你說(shuō)我怎么就攤上這事《魑牛” “怎么了艺糜?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)幢尚。 經(jīng)常有香客問(wèn)我破停,道長(zhǎng),這世上最難降的妖魔是什么尉剩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任真慢,我火速辦了婚禮,結(jié)果婚禮上理茎,老公的妹妹穿的比我還像新娘黑界。我一直安慰自己,他們只是感情好皂林,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布园爷。 她就那樣靜靜地躺著,像睡著了一般式撼。 火紅的嫁衣襯著肌膚如雪童社。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天著隆,我揣著相機(jī)與錄音扰楼,去河邊找鬼。 笑死美浦,一個(gè)胖子當(dāng)著我的面吹牛弦赖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浦辨,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蹬竖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了流酬?” 一聲冷哼從身側(cè)響起币厕,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芽腾,沒(méi)想到半個(gè)月后旦装,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摊滔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年阴绢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了店乐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呻袭,死狀恐怖眨八,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情左电,我是刑警寧澤廉侧,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站券腔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拘泞。R本人自食惡果不足惜纷纫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陪腌。 院中可真熱鬧辱魁,春花似錦、人聲如沸诗鸭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)强岸。三九已至锻弓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝌箍,已是汗流浹背青灼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妓盲,地道東北人杂拨。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悯衬,于是被迫代替她去往敵國(guó)和親弹沽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容