字符串和字符串池


一、字符串

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()返回值都是相等的,其余方法都是互不相等且與上述幾種不相等。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM