一、字符串
1.字符串的創建
(1)直接創建:String s="Hello";
(2)new創建:String s=new String("Hello")
要注意空字符串和null是不相同的
public static void main(String[] args) { String s1=""; String s3=new String(); String s2=new String("");
String s4=null; System.out.println(s1.equals(s2)); //s1、s2相等都是空字符串 System.out.println(s2.equals(s3)); //s2、s3相等 System.out.println(s3.equals(s4)); //s1、s2、s3與s4不相等! }
除了new ("Hello")中的類型之外,還能有如下方式:
String s1="Hello1"; String s2=new String(s1); char []c={'H','e','l','l','o','2'}; String s3=new String(c); //但不能String s3=new String({'H','e','l','l','o'}); byte []b={'H','e','l','l','o','3'}; String s4=new String(b); StringBuffer sb=new StringBuffer(new String("Hell04")); String s5=new String(sb); StringBuilder sbu=new StringBuilder(new StringBuffer("Hello5")); String s6=new String(sbu); System.out.println(s1+s2+s3+s4+s5+s6);
可以看出還可以以byte[]、char[]、String、StringBuffer、StringBuilder均可作為String構造函數的參數。
(3)vauleOf()創建
普通數據類型 String s1=String.vauleOf(true);或者是int bl=54;String s1=String.vauleOf(bl);直接將其轉換為String.
引用數據類型通過調用成員方法toString()來將對象轉換為字符串。對於System.out.println(obj);若obj==null則會返回null。
Object o=null; System.out.println(o); //輸出null字符串
System.out.println(o.toString()); //運行拋出異常java.lang.NullPointerException
否則等同於語句System.out.println(obj.toString());
//toString()方法
再來探討一下toString()方法,如果調用它的是一個字符串對象包括String、StringBuffer、StringBuilder則會返回當前字符串,如果是基礎數據的引用,例如Integer、Character、Boolean則會返回對應的int、char、boolean等對應的數據字符串。如果是其他類對象,重寫toStirng()方法就不說了,但是未重寫方法就會輸出"包名.類名@哈希碼十六進制"(此處包含數組)。
class A { } public class Strings { public static void main(String[] args) { A a=new A(); A a0=new A(); System.out.println(a.toString()); System.out.println(a0); } }
輸出:
arraytest.A@70dea4e
arraytest.A@5c647e05
//System.out.println()方法
而我們常用的System.out.println()方法其實就是將參數轉化為字符串,而主要方法就是(3)中的構造方法,若是基本類型,就使用vauleOf(),若是非null引用類型就調用toString(),若是null類型數據就返回null(null不能直接作為參數,只能是某對象指向null,然后打印此對象的形式);
class A { } class B { public String toString() { return "BB"; } } char []c={'H','e','l','l','o','2'}; //數組 StringBuffer sb=new StringBuffer(new String("Hell04")); //字符串對象 Integer i=9; //基本類型的包裝類 boolean bl=false; //基本數據類型 Object o=null; //null A a=new A(); //非null無重寫 B b=new B(); //非null有重寫 System.out.println(c); //打印Hello2 System.out.println(c.toString()); //打印[C@70dea4e,地址 System.out.println(i); //9,調用toString() System.out.println(bl); //false,調用valueOf() System.out.println(o); //null,無法使用toString() System.out.println(a); //地址 System.out.println(b.toString()); //BB
值得一提的就是字符串數組,在直接打印時會輸出字符串內容,但在調用toString()方法時會打印地址[C@70dea4e,而其余類型數組都會打印地址[就是包名,C就是類名?
(4)直接+
兩個直接字符串相加。String s1="123"+"456"
字符串和其他相加時會采用和println相同的策略
byte []b={'H','e','l','l','o','3'};
Object o=null; String s1="123"+new Integer(456); String s2="123"+o; String s3="123"+false; String s4="123"+b; System.out.println(s1); //123456,調用toString() System.out.println(s2); //123null System.out.println(s3); //123false,調用valueOf() System.out.println(s4); //123[B@70dea4e,調用toString()
仍然來重點看一下字符數組,在+連接符下,會直接調用toString()從而返回其地址,不會訪問其內容,編程與其他類型數組一樣。
2.字符串的操作
(1)public String concat(String str)進行拼接操作,若str是空字符串,則還返回原來的引用。
public static void main(String []args) { String s1="123"; String s2="456"; System.out.println(s1); System.out.println(s1.hashCode()); s1=s1.concat(s2); System.out.println(s1); System.out.println(s1.hashCode()); }
輸出:123
48690
123456
1450575459 可以看出若str不為空就會返回一個新的引用。
(2)String replace(char oldChar,char newChar)將所有oldChar字符替換為newChar,String toLowerCase()、String toUpperCase()轉換大小寫,String trim()去空白字符,對於這些方法來說若不改變原有字符串的,例如replace()不含oldChar,轉換成小寫的不含小寫字符串,或不含空白字符等就不會修改原引用。String substring(int beginIndex)和String substring(int beginIndex,int endIndex)是截取從第beginIndex+1到結束的子字符串和從第beginIndex+1到nedIndex的子字符串。
(3)format()方法,先不贅述
(4)int length()返回長度,boolean isEmpty()返回是否為空,char charAt(int index)返回第index+1的字符;
int indexOf(int ch)查找ch第一次出現的位置,若不含此字符,返回-1,不要誤以為寫錯了,確實是參數為int類型,這里指的是Unicode碼。int indexOf(int ch,int fromIndex)功能相同但需要從大於等於fromIndex的下標(注意和第幾個區分)開始查找。int indexOf(String str)前提是str是子字符串,返回第一個字符的下標,int indexOf(String str,int fromIndex)類似。
int lastIndexOf(int ch)、int lastIndexOf(String str)返回最后一個符合條件的字符下標、最后一個符合的字符串的第一個下標,int lastIndexOf(int ch,int fromIndex)和int lastIndexOf(String str,int fromIndex)返回小於等於fromIndex的最后一個下標或字符串的第一個下標。(語文不好(lll¬ω¬),還是上例子吧)
String s="abcabcdabcde"; System.out.println(s.indexOf('b')); //1 System.out.println(s.indexOf('b',1)); //1,Ifirst('b')=1>=1,返回1
System.out.println(s.indexOf('b',2)); //4,Ifirst('b')=1<1,尋早下一個b,Ifirst('b')=4>=1,返回4
System.out.println(s.indexOf("abc",0)); //0 System.out.println(s.indexOf("abc",1)); //3,判斷abc字串首字符a字符下標和1的大小,若Ifirst('a')>=1,返回Ifirst('a'),否則找到下一個abc字符串再判斷直到符合 System.out.println(s.indexOf("ab",-1)); //0,第二個參數小於0與等於0等價與沒有第二個參數等價 System.out.println(s.lastIndexOf("ab")); //7 System.out.println(s.lastIndexOf('c',8)); //5,若Ilast('c')<=8,則返回Ilast('c'),可以看出9>8不符合,尋找下一個5符合 System.out.println(s.lastIndexOf("abc",7)); //7,先倒着找出“abc”字符串,然后判斷Ilast('a')=7<=7,所有返回7 System.out.println(s.lastIndexOf("abc",29)); //7,任何大於字符串長度的第二參數與沒有第二參數等價
其中的Ifirst('a')表示正向查找a字符符合條件的下標,Ilast自然是指逆序查找下標。
(5)字符串的比較int compareTo(String another) (參數不能是null???),返回值第一個不相同字符unicode碼差值,若兩一個字符串是另一字符串字串,返回字符串長度差值,若兩串相同則返回0.此外還有int compareToIgnoreCase(String another)比較方法與其類似,但忽略掉大小寫。
判斷兩字符串相等不能用等號==(后面長篇幅介紹)要用boolean equals(Object anObj)你沒看錯正是Object類型的參數,但你用其他對象做參數他返回false,即使是StringBuffer對象也一樣,null可以作為參數但會永遠返回false,因為調用此成員方法永遠不會是null。boolean equalsIgnoreCase(String another)忽略大小寫。
(6)將字符串轉為基本類型parseXxx.例如轉為double型 public static double parseDouble(String s) throws NumberFormatException 可以看出要想轉換為double你的字符串必須要符合相應格式。但有一個例外parseBoolean除非字符串是“true”或“TRue”等返回true,其余均返回false,也就是說可以不符合格式。注:char類型可以直接由charAt方法獲得。
轉換為byte數組public byte[] getBytes()、轉換為字節數組public char[] toCharAyyay()。
二、字符串池(重點)
(1)直接賦值:String s="123456";先查找字符串池中是否有該字符串,若沒有則創建一個對象,並返回。若有此字符串直接返回。【創建1個對象】
(2)new創建:String s=new Stirng("123456");先查找字符串池中是否有該字符串,若有直接在堆中new一個對象並返回,沒有就在字符串中先創建一個,然后再在堆中new一個返回。【創建2個對象】
(3)+連接兩個字符串:String s="123"+"456";分別判斷字符串“123”和"456"在字符串池中是否存在,若不存在就創建一個。然后判斷連接后的字符"123456"在字符串池中是否存在,若不存在就創建。【3個對象】
(4)+連接對象和對象或連接對象和字符串:String s1="123";String s2=s1+"456"; String s3="456";String s4=s1+s3;具體情況有待證實,應該是先創建"123"對象(包括判斷),然后創建“456”對象,…………
(5)new字符串對象或+連接:String s1="123456";String s2=new(s1); String s3="123";String s4=new String(s3+"456");
(6)intern()方法:若字符串池中有字符串直接返回,否則創建一個對象。
String s="123456"; String s1="123456"; String s2=new String("123456"); String s3="123"+"456"; String s4="123"; String s5=s4+"456"; String s6="456"; String s7=s4+s6; String s8=new String(s1); String s9=new String(s4+"456"); System.out.println(s1==s); //true System.out.println(s1==s2); //false System.out.println(s1==s3); //true System.out.println(s1==s5); //false System.out.println(s1==s7); //false System.out.println(s1==s8); //false System.out.println(s1==s9); //false System.out.println(s==s2.intern()); //true System.out.println(s2==s2.intern());//false System.out.println(s2.intern()==s5.intern());//true
可以總結一下,賦值字符串直接量和幾個字符串直接量的連接和相同字符串的intern()返回值都是相等的,其余方法都是互不相等且與上述幾種不相等。