java 字串,字串緩衝區__java基礎

來源:互聯網
上載者:User

本文學習並總結java中的字串。內容包括String字串常用方法、StringBuffered和StringBuilder功能介紹,學習中練習了論壇中的一些提問問題,同時也對所學知識進行了驗證鞏固。

String類

String是java的字串類,被final修飾,不能被繼承,java 程式中的所有字串字面值(如"abc" )都作為此類的執行個體實現。
java中字串是常量,一旦被初始化就不可以被改變,對String對象的任何改變,都是返回一個新的String對象。

字串常量池

先說下常量池,每個類都有相應的常量池,常量池(constant pool)指的是在編譯期被確定,並被儲存在已編譯的.class檔案中的一些資料。它包括了關於類、方法、介面等中的常量,字串常量池是常量池的一部分。
jvm啟動前,一個類的字串常量池資訊就已經被確定,寫在.class檔案中,jvm啟動後,字串常量池被載入到記憶體中的方法區。
字串常量池中,每個字串常量都是唯一的,沒有相同字面值的多個副本。
字串常量池由String類私人地維護。
程式運行時,可以通過String類的intern()方法動態地擴充字串常量池。當調用 intern 方法時,如果池已經包含一個等於此String對象的字串(用 equals(object)方法確定),則返回池中的字串。否則,將此String 對象添加到池中,並返回此String對象的引用。所有字面值字串和字串賦值常量運算式都使用 intern 方法進行操作。

public class StringDemo1 {public static void main(String[] args) {String s1="abc";//建立String型引用變數s1,指向字串常量池中的"abc"字串。String s2=new String("abc");//棧中建立s2引用變數,堆記憶體中建立"abc"字串對象,並被s2指向。String s3="a"+"bc";//"a"和"bc"合成為字串常量"abc",先在字串常量池中尋找是否已有"abc"字串對象,已有,不再重新建立對象,s3和s1指向的是字串常量池中的同一個對象,s1==s3.String s4="a"+new String("bc");//在堆中建立了"bc"對象,與"a"相加,返回新的字串對象賦給s4,s4還指向堆中的字串對象。System.out.println(s1==s2);//falseSystem.out.println(s1==s3);//trueSystem.out.println(s1==s4);//falseSystem.out.println(s2==s4);//falseSystem.out.println(s1.equals(s2));//trueSystem.out.println("=============================");String s5=new String("def");//實際建立了2個對象,編譯完成後字串常量池中就有了"def",運行時在堆記憶體中建立String類對象"def".String s6="def";System.out.println(s5==s6);//false, s5指向堆記憶體中的"def"對象,s6是指向字串常量池中的"def"字串對象。System.out.println(s6==s5.intern());//true, s5.intern()指向字串常量池中的"def"字串對象。}}

字串常見操作
1. 擷取
1) 擷取字串的長度: int length()
2) 根據位置擷取該位置上的字元:
 char charAt(int index),index越界時,會發生StringIndexOutOfBoundsException異常。
3) 根據字元(子串)擷取該字元(子串)在串中的位置: 
 int index(int ch), 參數為字元的ASCII碼,返回ch在字串中第一次出現的位置,字串中沒有ch時返回-1;
 int index(int ch,int fromIndex), 從fromIndex位置開始搜尋,沒有時返回-1;
 int index(String str), 擷取字串str在另一個字串中第一次出現的位置,沒有時返回-1;
 int lastIndex(int ch), 反向搜尋,返回ch最後出現的位置。
2. 判斷
1) 字串是否包含某一子串: 
boolean contains(String str), 其實通過index(String str)方法完全可以實現此功能;
2) 字串是否以指定內容開頭:boolean startWith(String str) ;
3) 字串是否以指定內容結尾:boolean endWith(String str) ;
以上3個方法合起來可以實現常見的檔案名稱搜尋。
4) 字串是否有內容:boolean isEmpty(), jdk1.6版本開始才有,此方法的原理就是判斷字串長度是否為0;
5) 判斷字串內容是否相同:boolean equals(String str);
6)  判斷字串內容是否相財,忽略大小寫: boolean equalsIgnoreCase(String str);
3. 轉換
1) 將字元數組轉成字串
可以使用String類建構函式:String(char[]), String(char[],offset,count);
還可以使用String類的靜態方法:static String copyValueOf(char[])
                                                      static String copyValueOf(char[],offset,count)
                                                     static String valueOf(char[])
2) 將字串轉成字元數組:char[] toCharArray()
3) 將位元組數組轉成字串:與字元數組轉字串基本完全一樣,將char[]換成byte[]即可
4) 將字串轉成位元組數組:byte[] getBytes[]
字串和位元組數群組轉換時,可以指定編碼錶,這裡穿插說一會編碼、解碼的知識。
編碼:字串變成位元組數組。解碼:位元組數組變成字串。
常用的幾種字元集
Ascii碼字元集,用1個位元組來表示,第1位為0,剩餘7位表示總共127個字元,這顯然不能滿足英語之外的很多語言;
ISO8859-1編碼,歐洲編碼錶,單位元組編碼,ISO 8859-1相容ASCII碼,在ASCII碼空置的0xA0-0xFF的範圍內,加入了96個字母及符號,藉以供使用變音符號的拉丁字母語言使用,ISO 8859-1又稱Latin-1;
GB2312/GBK/GBK18030, 漢字的國標碼,用2個位元組表示一個漢字。GB2312隻用表示簡體字,包含6千多個漢字,GBK完全反向相容GB2312編碼,GBK編碼能夠用來同時表示繁體字和簡體字,包含2萬多個漢字,GBK還可編碼英文字母,英文字母編碼相容iso8859-1編碼(英文字母用一個位元組表示)。GBK後來又擴充成GBK18030.
Unicode,國際標準碼值,所有字元用定長雙位元組表示(定長編碼電腦處理方便),可以用來表示所有語言的字元,包括英文字母;unicode不相容任何編碼,不過,相對於iso8859-1編碼來說,Uniocode編碼只是在前面增加了一個0位元組,比如字母'a'為"00 61"。
UTF-8,國際標準碼值,可以用來表示所有語言中的字元;變長位元組編碼,每一個字元的長度從1-3個位元組不等,能用一個位元組裝下的就用一個位元組表示,依次類推。一般來說,英文字母都是用一個位元組表示,相容iso8859-1,而漢字使用三個位元組,同一個漢字在UTF-8和GBK中的編碼可能不一樣。

import java.io.UnsupportedEncodingException;import java.util.Arrays;public class EncodeDemo {public static void main(String[] args) throws UnsupportedEncodingException {String a="你好";byte[] b1=a.getBytes("GBK"); //編碼預設字元集就是GBK,所以可不寫。System.out.println(Arrays.toString(b1));String s1=new String(b1,"GBK");//解碼預設字元集也是"GBK",此處"GBK"也可以不寫.System.out.println(s1);byte[] b2=a.getBytes("UTF-8"); //使用UTF-8字元集編碼System.out.println(Arrays.toString(b2));//b1長度是6,UTF-8中一漢字佔3個位元組。String s2=new String(b2,"GBK");//UTF-8編碼的byte數組,用GBK解碼,每2個位元組去匹配GBK解碼錶,出現亂碼System.out.println(s2);//byte[] b3=a.getBytes("ISO8895-1"); //運行後報異常java.io.UnsupportedEncodingException;因為iso8859-1字元集中沒法識別中文字,不能對漢字編碼;字串一旦編碼失敗,就再也不能解碼成功了。byte[] b4=a.getBytes("GBK");System.out.println(Arrays.toString(b4));//b1長度是6,UTF-8中一漢字佔3個位元組。String s4=new String(b4,"ISO8859-1");//編碼成功,但解碼錯誤 ,可以補救,將b4先用iso8895-1解碼,然後再用GBK解碼。System.out.println(s4);byte[] b5=s4.getBytes("ISO8859-1");System.out.println(Arrays.toString(b5));String s5=new String(b5,"GBK");System.out.println(s5);;}}運行結果:[-60, -29, -70, -61]你好[-28, -67, -96, -27, -91, -67]浣犲ソ[-60, -29, -70, -61]????[-60, -29, -70, -61]你好
5) 將基礎資料型別 (Elementary Data Type)轉成字串: static String valueOf(int/byte/double等)。

4. 替換
String replace(oldChar,newChar), String replace(oldStr,newStr), 如果要替換的字元或字串不存在,則返回原串。
5. 切割
String[] split(String regex);
注意,若用“.”和“|”切割字串,因這2者都是逸出字元,必須得加"\\",即str.split("\\.")和str.split("\\|")。
6. 擷取子串
1) String subString(begin,end),返回的子串角標含begin,但不含end,含頭不含尾;
2) String subString(begin), 等價於subString(begin, str.length())。
7. 去除空格,比較
1) 將字串轉成大寫或小寫: String toUpperCase(), String toLowerCase()
2) 將字串兩端的多個空格去掉:String trim()
3) 對2個 字串進行自然順序的比較:
int CompareTo(str), 相等時返回0,否則返回2個串中第1個不相等的字元的ASCII碼值的差。
下面是String類相關的2個練習題,題目本身解決的問題也比較有意義,放在這裡作個記錄:

/* 問題:輸入無重複字元的字串,輸出這些字元的全排列。*//* 思路:基本就是按照數學中排列組合的原理,對多個字元排列時,可以遞迴分成第一個字元與剩餘字元組成字元子串的全排列的組合。*/import java.lang.*;import java.util.*;class QuanPL{    public static void main(String[] args){        String str="abc";       // System.out.println((allMaxLen(str)).size());       // System.out.println(allMaxLen(str));       System.out.println(all(str));    }    //字串全排列,長度從1到str.length()    public static ArrayList<String> all(String str){    ArrayList<String> al=new ArrayList<String>();    if(str.length()==1){    al.add(str);    return al;    }else{        String sa=str.charAt(0)+"";    al.add(sa);    String sub=str.replace(sa,"");    //對子串進行遞迴    ArrayList<String> tk=all(sub);    al.addAll(tk);    Iterator<String> it=tk.iterator();    String s=null;    while(it.hasNext()){    s=it.next();    for(int j=0;j<=s.length();j++){       //遍曆sa添加到s上時的位置    al.add(s.substring(0,j)+sa+s.substring(j,s.length()));    }    }    }    return al;    }    //長度為str.length()的字串全排列。    public static ArrayList<String> allMaxLen(String str){        ArrayList<String> al=new ArrayList<String>();        if(str.length()==1){            al.add(str);            return al;                    }else{            char[] ch=str.toCharArray();            for(int i=0;i<ch.length;i++){//對排列第1個位置上的可取字元進行遍曆                String sub=str.replace(ch[i]+"","");                ArrayList arr=allMaxLen(sub); //遞迴對除去第1個位置上字元的剩餘子串進行排列                //System.out.println(arr);                Iterator<String> it=arr.iterator();                while(it.hasNext()){                    String s=new String();                    //String ss=it.next();                    String re=ch[i]+it.next();//合起來就是整個字串了                    al.add(re);                }            }            return al;                    }            }}
/*尋找2個字串中相同的最大子串,如果有2個或多個不同的最大相同子串,放在一個ArrayList對象中全部返回。*/import java.util.*;class Test5{public static void main(String[] args){         String s1="kiokk";          String s2="kib3oktr";         System.out.println(maxSubstring(s1,s2));}public static ArrayList maxSubstring(String s1,String s2){                String max,min;                int len=0; //用於儲存最大子串的長度                ArrayList<String> al=new ArrayList<String>(); //用於儲存最大子串                              max=(s1.length()>s2.length())? s1:s2;                min=(max==s1)? s2:s1;                System.out.println(max+"....."+min);                for(int x=0;x<min.length();x++){                        for(int y=0,z=min.length()-x;z!=min.length()+1;y++,z++){                                String temp=min.substring(y,z);                                temp.toCharArray();                                //String[] q=null;                                 //System.out.println("temp="+temp);                                if(max.contains(temp)){                                                                 //System.out.println("結果是"+temp);                                if(temp.length()>=len){ //代碼首先產生的相同子串的長度肯定是最大的,所以這樣判斷 沒問題,後續還有相同長度的子串時也加入到al中                                len=temp.length();                                                                al.add(temp);                                }                                }                                                                      }                }                return al;}}//運行結果會將輸出ok,kk.
StringBuffer類

字串緩衝區,是一個容器, final類,不能被繼承。
特點:長度可變化;可以直接操作多個資料類型;最終會通過toString()方法轉成字串。

StringBuffer作為一個容器,可以進行增刪改查等操作。
1. 儲存
StringBuffer append(), 參數可以為String對象、StringBuffer對象、6種基礎資料型別 (Elementary Data Type)(除byte和short)、字元數組(可以指定offset和count),將指定參數添加到已有資料結尾處,返回原對象。
StringBuffer insert(index, 資料), 將資料插入到指定index位置,index超過字串當前最大位置時,會有角標越界異常。
2. 刪除
StringBuffer delete(start,end),刪除緩衝區中的資料,含頭不含尾
StringBuffer delete(charAt(index)), 刪除指定位置上的字元
StrubgBuffer delete(0,sb.length()),清空緩衝區
3.擷取
char charAt(int index)
int indexOf(String str)
int lastIndexOf(String str)
int length()
String subString(int start,int end)
4. 修改
void setCharAt(int index,char c)
StringBuffer replace(start,end,String str)
5. 反轉
StringBuffer reverse()
6. getChars()方法
void getChars(int srcBegin,int srcEnd,char[] det,int detBegin), 將緩衝區中指定資料存放區到目標字元數組中。
StringBuffer的一個巧妙應用樣本:

/* 問題:把abcd...s共19個字母組成的序列重複拼接106次,得到長度為2014的串。    接下來刪除第1個字母(即開頭的字母a),以及第3個,第5個等所有奇數位置的字母。    得到的新串再進行刪除奇數位置字母的動作。如此下去,最後只剩下一個字母,請寫出該字母。 */public class StringBufferDemo {         public static void main(String[] args)         {                 String str = "abcdefghijklmnopqrs";                 String ss=new String();                 //將字串拼接106次                for (int i = 0; i < 106; i++)                 {                ss=ss+str;                 }                System.out.println(remove(ss));         }         public static String remove(String str){         StringBuffer strbu=new StringBuffer(str);         while (1!= strbu.length())  //最後剩下一個字母,故迴圈結束條件為最後的長度為1             {                     for (int i = 0; i < strbu.length(); i++)                     {                             /*如果將字串看成一個字元數組,那麼按照題目的意思,就是刪除數組中所有下標為偶數(包括0)的字母,                              * 但當刪除當前i處的字母時,後邊的字母會向前移動一個字元,這樣,當前已被刪的字母的下一個字母其實已經移到i處了,而此時i已經自增了1,                              * 所以i剛好就是下下個字母的索引,也就是下一個偶數位位置。                              */                            strbu.deleteCharAt(i);  //刪除索引i處的字母                     }             }             return strbu.toString();   //最後結果是q                  } }

StringBuild類

是StringBuffer的一個簡易替換,jdk1.5版本起才有的。

與StringBuffer的不同之處:
StringBuffer是同步的,安全執行緒,但每次操作時都要判斷鎖,效率低
StringBuilder是線程不同步的,不用判斷鎖,效率高,執行緒安全性要求高時可以手動同步。
開發建議使用StringBuilder.



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.