如果覺得我寫的還行,請關注我的博客並且點個贊喲。本文主要介紹JAVA 中最常使用字符串常量String相關知識。
1.String簡介
2.創建字符串對象兩種方式的區別
3.String常用的方法
4.String的不可變性
5.一道阿里面試題,你會做嗎?
1.String簡介
1.1String源碼
首先看一段String源碼,String主要實現了Serializable、Comparable、CharSequence等接口。Serializable主要實現序列化,Comparable此接口強行對實現它的每個類的對象進行整體排序,CharSequence主要實現char值的一個可讀序列。String使用final關鍵字修飾,表明String這個類是不能被繼承。
在API中對String是這樣描述:
String 類代表字符串。Java 程序中的所有字符串字面值(如 “cc程序員” )都作爲此類的實例實現。字符串是常量;它們的值在創建之後不能更改。字符串緩衝區支持可變的字符串。因爲 String 對象是不可變的,所以可以共享。
String str = "abc";
相當於:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
1.2.String中的成員變量
@Stable
//String的屬性值
private final byte[] value;
// coder方法判斷COMPACT_STRINGS爲true的話,則返回coder值,否則返回UTF16; isLatin1方法判斷COMPACT_STRINGS爲true且coder爲LATIN1則返回true
private final byte coder;
//String類型的hash值
private int hash;
private static final long serialVersionUID = -6849794470754667710L;
//默認爲true
static final boolean COMPACT_STRINGS = true;
//創建串行化字段
private static final ObjectStreamField[] serialPersistentFields
= new ObjectStreamField[0];
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new String.CaseInsensitiveComparator();
static final byte LATIN1 = 0;
static final byte UTF16 = 1;
1.3.String的構造函數
2.創建字符串對象兩種方式的區別
1.直接賦值方式創建對象
直接賦值方式創建對象是在方法區的常量池
String str="cc程序員";//直接賦值的方式
2.通過構造方法創建字符串對象
通過構造方法創建字符串對象是在堆內存
String str=new String("cc程序員");//實例化的方式,New一個對象
3.String常用的方法
3.1.String 的判斷操作
//測試此字符串是否以指定的前綴開頭
startsWith(String prefix)
//試在指定索引處開始的此字符串的子字符串是否以指定的前綴開頭
startsWith(String prefix, int toffset)
//測試此字符串是否以指定的後綴結尾。
endsWith(String suffix)
//將此字符串與指定對象進行比較。 其結果是true當且僅當該參數不是null
//並且是String對象,表示相同的字符序列作爲該對象。
equals(Object anObject)
//將此字符串與指定的StringBuffer進行StringBuffer 。
//其結果是true如果並且如果該只String表示的字符作爲指定的相同序列StringBuffer 。
// 該方法在StringBuffer上StringBuffer
contentEquals(StringBuffer sb)
//將此String與其他String比較,忽略案例注意事項。
//如果兩個字符串的長度相同,並且兩個字符串中的相應字符等於忽略大小寫,
//則兩個字符串被認爲是相等的
equalsIgnoreCase(String anotherString)
代碼事例如下:
package com.cy.lambda.learning.base;
/**
* cc程序員
* String實例
*/
public class StringDemo {
public static void main(String[] args) {
String s1 = "cc程序員";
String s2 = "CC程序員";
StringBuffer sb = new StringBuffer("cc程序員");
System.out.println("===:"+s1 == s2);//false
//startsWith(String prefix)測試此字符串是否以指定的前綴開頭
System.out.println("startsWith(String prefix):"+s1.startsWith(s2));//false
/**
* startsWith(String prefix, int toffset)試在指定索引處開始的此字符串
* 的子字符串是否以指定的前綴開頭
*/
System.out.println("startsWith(String prefix, int toffset):"
+s1.startsWith(s2,3));//false
// endsWith(String suffix)測試此字符串是否以指定的後綴結尾。
System.out.println("endsWith:"+s1.endsWith("員"));//true
/**
* equals(Object anObject)將此字符串與指定對象進行比較。
* 其結果是true當且僅當該參數不是null並且是String對象,
* 表示相同的字符序列作爲該對象。
*/
System.out.println("equal:"+s1.equals(s2));//true
/**
* contentEquals(StringBuffer sb)將此字符串與指定的StringBuffer進行StringBuffer
* 其結果是true如果並且如果該只String表示的字符作爲指定的
* 相同序列StringBuffer 。該方法在StringBuffer上StringBuffer
*/
System.out.println("contentEquals:"+s1.contentEquals(sb));//true
/**
* equalsIgnoreCase(String anotherString)
* 將此String與其他String比較,忽略案例注意事項。
* 如果兩個字符串的長度相同,並且兩個字符串中的相應字符等於忽略大小寫,
* 則兩個字符串被認爲是相等的
*/
System.out.println("equalsIgnoreCase:"+s1.equalsIgnoreCase(s2));//true
//length() 字符串長度
System.out.println(s1.length());
}
}
4.String的不可變性
String是個常量,從一出生就註定不可變.正如文章開頭介紹一樣,String類被final修飾,所以她是不可變得。
因爲String太過常用,JAVA類庫的設計者在實現時做了個小小的變化,即採用了享元模式,每當生成一個新內容的字符串時,他們都被添加到一個共享池中,當第二次再次生成同樣內容的字符串實例時,就共享此對象,而不是創建一個新對象,但是這樣的做法僅僅適合於通過=符號進行的初始化。
需要說明一點的是,在object中,equals()是用來比較內存地址的,但是String重寫了equals()方法,用來比較內容的,即使是不同地址,只要內容一致,也會返回true,這也是爲什麼a.equals©返回true的原因了。
可以實現多個變量引用堆內存中的同一個字符串實例,避免創建的開銷。
String不可變得好處:
我們的程序中大量使用了String字符串,有可能是出於安全性考慮。
大家都知道HashMap中key爲String類型,如果可變將變的多麼可怕。
當我們在傳參的時候,使用不可變類不需要去考慮誰可能會修改其內部的值,如果使用可變類的話,可能需要每次記得重新拷貝出裏面的值,性能會有一定的損失
5.如何實現兩金額數據相加(最多小數點兩位)(阿里面試題)
如果你想知道答案或者你知道答案,請留言或者關注下方公衆號,並且回覆1030,將會得到答案和解析喲。
如果你覺得我寫的還行,請關注我的博客並且點個贊喲,也請關注我的公衆號並加入下方QQ羣,每天都會定時推送乾貨以及共享一些優質的學習資料和視頻喲.