Java常用類(String, StringBuffer, StringBuilder)

一、String類

String的實(shí)例化方式

  • 通過(guò)字面量定義的方式
String str = "hello world";
  • 通過(guò)new+構(gòu)造器的方式
String str = new String("hello world");
  • 面試題:String s = new String("asf");方式創(chuàng)建對(duì)象,在內(nèi)存中創(chuàng)建了幾個(gè)對(duì)象金闽?
    答:兩個(gè)搬葬,一個(gè)是堆空間中new出來(lái)的,一個(gè)是char[ ]對(duì)應(yīng)的常量池中的數(shù)據(jù):“abc”

String類的內(nèi)部細(xì)節(jié)

  • String表示字符串汁展,使用一對(duì)“”引起來(lái)表示
  • String聲明為final,不可被繼承
  • String實(shí)現(xiàn)了Serializable接口,表示字符串是支持序列化的虏等;實(shí)現(xiàn)了Comparable接口弄唧,表示String是可以比較大小的
  • String內(nèi)部定義了final char[ ] value 用于存儲(chǔ)字符串?dāng)?shù)據(jù)
  • String代表不可變的字符序列,簡(jiǎn)稱:不可變性??體現(xiàn)在如下三個(gè)方面
    ①對(duì)字符串重新賦值時(shí)霍衫,需要重新指定內(nèi)存區(qū)域賦值候引,不能使用原有的value進(jìn)行賦值
    ②當(dāng)對(duì)現(xiàn)有字符串進(jìn)行連接操作時(shí),也需要重新指定內(nèi)存區(qū)域敦跌,不能對(duì)原有的value進(jìn)行賦值
    ③當(dāng)調(diào)用String的replace方法修改指定字符或者字符串時(shí)澄干,也需要重新指定內(nèi)存區(qū)域
  • 通過(guò)字面量的方式(區(qū)別于new)給一個(gè)字符串賦值,此時(shí)的字符串聲明在字符串常量池中
  • 字符串常量池中是不會(huì)存儲(chǔ)相同的字符串的

String賦值的各種內(nèi)存結(jié)構(gòu)

  • String的部分構(gòu)造器源碼(用于輔助理解其不可變性以及兩種初始化方式)
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
 /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence.  Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
    public String() {
        this.value = "".value;
    }
 /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    /**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);    //見(jiàn)如上注釋柠傍,copy的目的是對(duì)于數(shù)組的操作不會(huì)影響String的值
    }
}
  • 例子
public class StringTest1 {
    public static void main(String[] args) {
        String str1="abc";
        String str2="abc";
        String str3=new String("abc");
        String str4=new String("def");
        System.out.println(str1==str2);
        System.out.println(str1==str3);

    }
}

內(nèi)存結(jié)構(gòu)圖

(現(xiàn)在的知識(shí)有限麸俘,具體的細(xì)節(jié)我也不太懂,比如我不知道常量池里放的是否是對(duì)象惧笛,他們和數(shù)組的關(guān)系是不是應(yīng)該這樣放从媚,我是按照視頻里老師講的和源碼,自己理解為這樣的患整,有錯(cuò)的話希望幫忙指出)

String的常用操作

  • 連接字符串(+)
String s1="hello";
String s2="world";
String s3="hello"+"world";
String s4=s1+"world";
String s5=s1+s2;
String s6=(s1+s2).intern();
System.out.println(s3==s4);
System.out.println(s3==s5);
System.out.println(s4==s5);
System.out.println(s3==s6);

注意事項(xiàng):
①常量與常量的拼接結(jié)果放在常量池中拜效,且常量池中不會(huì)存在相同內(nèi)容的常量
②只要其中一個(gè)是變量,結(jié)果就在堆中
③如果拼接的結(jié)果調(diào)用intern方法各谚,返回值就在常量池中
題目:

final String str="123";
String str1=str+"abc";
String str2="123abc";
System.out.println(str1==str2);  //true

解釋:此時(shí)的str是常量拂檩,參照①

  • int length() 輸出數(shù)組的長(zhǎng)度,實(shí)際上是底層的數(shù)組的長(zhǎng)度
  • char chatAt(int index) 返回index索引處的字符嘲碧,實(shí)際上是return value[index];
    ??區(qū)別于C++的可以對(duì)字符串按照字符數(shù)組的方式進(jìn)行訪問(wèn)修改稻励,在java中,字符串是對(duì)象愈涩,應(yīng)該使用對(duì)象的方法對(duì)字符串進(jìn)行訪問(wèn)望抽、修改等操作
  • boolean isEmpty() 判斷當(dāng)前數(shù)組是否為空,return value.length==0;
  • String toLowerCase() / toUpperCase() 將字符都變?yōu)樾懟虼髮?/li>
String str1="ASDFG";
String str2=str1.toLowerCase();
//str1不變履婉,印證了String的不變性
System.out.println(str1);
System.out.println(str2);
  • String trim() 返回值是去除原字符串首尾空格的副本煤篙,原字符串不變
  • boolean equals(Object obj) 比較字符串的內(nèi)容是否相同
    boolean equalsIgnoreCase(Object obj) 忽略大小寫比較
  • String concat(String str) 將指定字符串連接到此字符串的結(jié)尾,等價(jià)于“+”
  • int compareTo(String str) 比較兩個(gè)字符串的大小 負(fù)數(shù)毁腿,則當(dāng)前對(duì)象屑巍;整數(shù)已烤,則str小
  • String substring(int beginIndex) 返回一個(gè)新的字符串鸠窗,該字符串是從beginIndex開(kāi)始截取到最后
  • String substring(int beginIndex, int endIndex) 返回一個(gè)新的字符串,該字符串是從beginIndex開(kāi)始截取到endIndex-1的位置(左閉右開(kāi))
    ??在上述方法中胯究,只要是對(duì)字符串進(jìn)行了操作的稍计,原字符串仍然保持不變,最終生成的結(jié)果是通過(guò)return的形式返回裕循,所以對(duì)字符串操作的方法的返回值都是String類型的(再次注意字符串的不變性)

  • boolean endsWith(String suffix) 測(cè)試此字符串是否以指定的后綴結(jié)束
    boolean startsWith(String prefic) 測(cè)試字符串是否以指定的前綴開(kāi)始
    boolean startsWith(String prefic臣嚣,int toffset) 測(cè)試此字符串從指定位置開(kāi)始的子串是否以指定的前綴開(kāi)始
  • boolean contains(CharSequence s)當(dāng)前字符串中是否包含字符序列s净刮,CharSequence 是一個(gè)字符序列接口(典型的實(shí)現(xiàn)類是String,StringBuffer,StringBuilder), 此處可以傳入一個(gè)String硅则,但不能是字符數(shù)組

  • int indexOf(String str) 返回指定字符串在此字符串中第一次出現(xiàn)的索引位置
    int indexOf(String str, int fromIndex) 返回指定字符串在此字符串中從fromIndex開(kāi)始第一次出現(xiàn)的索引位置(可以用來(lái)尋找當(dāng)前字符串中str出現(xiàn)的次數(shù))
    int lastIndexOf(String str) 返回最右出現(xiàn)的索引位置
    int lastIndexOf(String str, int fromIndex) 返回最右出現(xiàn)的索引位置,從指定的索引開(kāi)始反向搜索(從index開(kāi)始向左搜索淹父,如果index指的位置正好是最后一次出現(xiàn)的位置,則返回index)

  • String replace(char oldChar, char newChar) 返回一個(gè)新的字符串怎虫,它是通過(guò)用newchar替換此字符串中出現(xiàn)的所有oldChar得到的
  • String replace(CharSequence target, CharSequence replacement) 返回一個(gè)新的字符串弹灭,使用指定的字符序列替換此字符串中所有匹配的字符序列
  • String replaceAll(String regex, String replacement) 使用給定的replacement替換此字符串中所有匹配給定正則表達(dá)式的子字符串
  • String replaceFirst(String regex, String replacement) 使用給定的replacement替換此字符串中匹配給定正則表達(dá)式的第一個(gè)子字符串

  • boolean matches(String regex) 判斷此字符串是否匹配給定的正則表達(dá)式

  • String[] split(String regex) 根據(jù)給定正則表達(dá)式的匹配拆分此字符串(符合正則表達(dá)式的部分不出現(xiàn)在最終結(jié)果中)
  • String[] split(String regex, int limit) 根據(jù)給定正則表達(dá)式的匹配拆分此字符串,最多不超過(guò)limit個(gè)揪垄,如果超過(guò)了剩下的全部放在最后一個(gè)元素中
String test="hhh,fff,ggg,aaa,ddd,eee,rrrr";
        String[] res=test.split(",");
        for(int i=0;i<res.length;i++){
            System.out.println(res[i]);
        }
        System.out.println("-------------");
        String[] res2=test.split(",",3);
        for(int i=0;i<res2.length;i++){
            System.out.println(res2[i]);
        }
image.png

String與其他類型的轉(zhuǎn)換

  • String與基本數(shù)據(jù)類型和包裝類的轉(zhuǎn)換
    基本數(shù)據(jù)類型/包裝類 --> String :String.valueOf()或者與空字符串進(jìn)行連接
    String --> 基本數(shù)據(jù)類型/包裝類 :包裝類.parseXXX()
    (以int為例)
    (好像valueOf方法都是把形參轉(zhuǎn)換成當(dāng)前類對(duì)象的)
public class StringTest1 {
    @Test
    public void test1(){
        //int轉(zhuǎn)String
        int a=123;
        String str1=String.valueOf(a);
        String str2=""+a;
        System.out.println(str1);
        System.out.println(str2);

        //String轉(zhuǎn)int
        int b=Integer.parseInt(str1);
        System.out.println(b);

    }
}
  • public void getChars(int start,int end,char c[],int offset)
    該方法的作用是將當(dāng)前字符串從start到end-1位置上的字符復(fù)制到字符數(shù)組c中穷吮,并從c的offset處開(kāi)始存放
  • String與char[]的轉(zhuǎn)換
    String --> char[] : toCharArray()
    char[] --> String : 構(gòu)造器
@Test
    public void test2(){

        //string to char[]
        String str="asf";
        char[] chars=str.toCharArray();
        for(int i=0;i<chars.length;i++){
            System.out.println(chars[i]);
        }

        //char[] to String
        String newStr=new String(chars);
        System.out.println(newStr);
    }
  • String與byte[ ]轉(zhuǎn)化
    String轉(zhuǎn)化為byte數(shù)組是字符編碼的過(guò)程,底層都是以字節(jié)碼的形式進(jìn)行存儲(chǔ)饥努;byte數(shù)組轉(zhuǎn)化為String是解碼的過(guò)程捡鱼。String轉(zhuǎn)化為字節(jié)碼的時(shí)候可以選擇編碼集,在utf-8中一個(gè)中文字符用三個(gè)字節(jié)表示酷愧,在gbk中用兩個(gè)字節(jié)表示驾诈,所以解碼使用的編碼集應(yīng)該與編碼使用的相同,才能解出正確的結(jié)果
    String --> byte[] : getBytes()
    byte[] --> String : 構(gòu)造器
@Test
    public void test3(){

        //String to byte[]
        String str="123abc中國(guó)";
        byte[] bytes_utf8=str.getBytes();
        for(int i=0;i<bytes_utf8.length;i++){
            System.out.print(bytes_utf8[i]+" ");
        }


        System.out.println();

        byte[] bytes_gbk=null;
        try {
            bytes_gbk=str.getBytes("gbk");
            for(int i=0;i<bytes_gbk.length;i++){
                System.out.print(bytes_gbk[i]+" ");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println();
        //byte[]  to String    
        String res1=new String(bytes_utf8);
        String res2=new String(bytes_gbk);    //我的編譯器使用的是utf-8解碼溶浴,所以會(huì)亂碼
        System.out.println(res1);
        System.out.println(res2);
    }
image.png

二乍迄、StringBuffer與StringBuilder

  • String、StringBuffer與StringBuilder三者的異同
    String:不可變的字符序列士败;底層使用char[ ]存儲(chǔ)
    StringBuffer:可變的字符序列闯两;線程安全的(synchronized),效率低谅将;底層使用char[ ]存儲(chǔ)
    StringBuilder:可變的字符序列漾狼;(jdk1.5)線程不安全的,效率高饥臂;底層使用char[ ]存儲(chǔ)
  • StringBuffer的部分源碼
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    /**
    以下用到的super構(gòu)造器為
    AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }
    */
    /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

     /**
     * Constructs a string buffer with no characters in it and
     * the specified initial capacity.
     *
     * @param      capacity  the initial capacity.
     * @exception  NegativeArraySizeException  if the {@code capacity}
     *               argument is less than {@code 0}.
     */
    public StringBuffer(int capacity) {
        super(capacity);
    }

    /**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * {@code 16} plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

    @Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }

}
  • StringBuffer的容量問(wèn)題
    StringBuffer內(nèi)部的兩個(gè)重要成員變量value[ ](存放字符串)和count(有效字符的個(gè)數(shù))逊躁,初始化StringBuffer時(shí)會(huì)多開(kāi)16個(gè)字符的大小作為value的長(zhǎng)度,調(diào)用length()返回的是有效字符的個(gè)數(shù)count隅熙,調(diào)用capacity()返回的是value數(shù)組的真實(shí)長(zhǎng)度
  • StringBuffer的擴(kuò)容問(wèn)題
    如果要append的東西稽煤,底層數(shù)組放不下了(超出了capacity),需要擴(kuò)容底層的數(shù)組囚戚。默認(rèn)情況下酵熙,擴(kuò)充為原來(lái)容量的2倍+2,同時(shí)將原有數(shù)組的元素復(fù)制到新數(shù)組中
    具體可以查看append的源碼
  • String由于不可變弯淘,效率最差绿店,開(kāi)發(fā)過(guò)程中如果字符串需要改變,建議使用StringBuffer和StringBuilder庐橙。并且假勿,總是擴(kuò)容也會(huì)影響到程序的效率,所以建議使用StringBuffer(int capacity)構(gòu)造器态鳖,提前設(shè)置好容量

StringBuffer(StringBuilder)的常用方法

  • StringBuffer append(xxxx) 提供了很多的append方法转培,用于進(jìn)行字符串拼接
  • StringBuffer delete(int start, int end) 刪除指定位置的內(nèi)容
  • StringBuffer replace(int start, int end, String str) 把[start,end)位置替換為str
  • StringBuffer insert(int offset, xxxx) 在指定位置插入xxxx
  • StringBuffer reverse() 把當(dāng)前字符序列逆轉(zhuǎn)
    (以上操作都是在StringBuffer/StringBuilder原底層數(shù)組上進(jìn)行操作浆竭,改變?cè)讓訑?shù)組存放的內(nèi)容浸须,返回類型是StringBuffer/StringBuilder,是因?yàn)閳?zhí)行了return this;邦泄,所以支持方法鏈的操作删窒,例如str.append("123456").reverse();

  • int indexOf(String str) 出現(xiàn)str的位置
  • String substring(int start, int end) 返回一個(gè)[start,end)的字符串
  • int length() 返回實(shí)際存放的元素的格式顺囊,與capacity區(qū)別開(kāi)
  • char charAt(int n) 返回下標(biāo)為n的字符
  • void setCharAt(int n, char ch) 將下標(biāo)為n的字符替換為ch

例題:

  • 創(chuàng)建一個(gè)字符串“ab12345cd"肌索,對(duì)字符串進(jìn)行操作,使其變?yōu)椤盿b54321cd"
import org.junit.Test;

/**
 * @Author: ssy
 * @Description:
 * @Date: Created in 9:28 2020/11/23
 * @Modified By:
 */
public class StringTest2 {
    @Test
    public void StringBuilderTest(){
        StringBuilder str=new StringBuilder("ab12345cd");
        str.replace(2,7,(new StringBuilder(str.substring(2,7))).reverse().toString());
        System.out.println(str);
    }
}

寫的時(shí)候還是應(yīng)該多注意返回類型的特碳;另外想不起庫(kù)函數(shù)诚亚,這種題完全可以自己手寫,和底層沒(méi)有太大的差別

  • 查找str1在str2中出現(xiàn)的次數(shù)
    僅僅是熟悉一下相關(guān)函數(shù)的操作午乓,不涉及算法知識(shí)站宗,追求高效的話還是要學(xué)KMP算法
import org.junit.Test;

/**
 * @Author: ssy
 * @Description:
 * @Date: Created in 16:38 2020/11/23
 * @Modified By:
 */
public class AlgorithmTest2 {
    @Test
    public void test(){
        String str1="aba";
        String str2="ababahjjlkhhlkabaljlnmababa";
        System.out.println(findCount(str1,str2));
    }

    /**
     *
     * @Description:
     * 查找str1在str2中出現(xiàn)的次數(shù)
     * @auther: ssy
     * @date: 16:40 2020/11/23
     * @param: [str1, str2]
     * @return: int
     *
     */
    public int findCount(String str1,String str2){
        int count=0;
        int index=0;
        if(str1.length()<str2.length()){
            while((index=str2.indexOf(str1,index))!=-1){
                count++;
                index++;
            }
            return  count;
        }
        else return 0;
    }
}

??面試題

說(shuō)出每一個(gè)輸出的執(zhí)行結(jié)果

@Test
    public void  testDebug(){
        String str=null;
        StringBuffer sb=new StringBuffer();
        sb.append(str);
        System.out.println(sb.length());   //4
        System.out.println(sb);  //"null"   沒(méi)有引號(hào),只是用來(lái)表示存儲(chǔ)內(nèi)容


        StringBuffer sb1=new StringBuffer(str);    //空指針異常
        System.out.println(sb1);     //由于出現(xiàn)異常不會(huì)執(zhí)行

    }

查看過(guò)源碼的話益愈,就會(huì)比較簡(jiǎn)單了

  • append的源碼對(duì)于添加空字符串做了特殊處理梢灭,會(huì)將null這四個(gè)字符存放在數(shù)組中,所以長(zhǎng)度增加4蒸其,數(shù)組中的內(nèi)容為‘n’ ‘u’ ‘l’ ‘l’
  • 構(gòu)造器StringBuffer(str)中執(zhí)行的操作為super(str.length()+16) 此時(shí)的str是空或辖,所以會(huì)出現(xiàn)空指針異常
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市枣接,隨后出現(xiàn)的幾起案子颂暇,更是在濱河造成了極大的恐慌,老刑警劉巖但惶,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耳鸯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡膀曾,警方通過(guò)查閱死者的電腦和手機(jī)县爬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)添谊,“玉大人财喳,你說(shuō)我怎么就攤上這事。” “怎么了耳高?”我有些...
    開(kāi)封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵扎瓶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我泌枪,道長(zhǎng)概荷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任碌燕,我火速辦了婚禮误证,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘修壕。我一直安慰自己愈捅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布慈鸠。 她就那樣靜靜地躺著蓝谨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪林束。 梳的紋絲不亂的頭發(fā)上像棘,一...
    開(kāi)封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音壶冒,去河邊找鬼缕题。 笑死,一個(gè)胖子當(dāng)著我的面吹牛胖腾,可吹牛的內(nèi)容都是我干的烟零。 我是一名探鬼主播,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼咸作,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锨阿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起记罚,我...
    開(kāi)封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤墅诡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后桐智,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體末早,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年说庭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了然磷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刊驴,死狀恐怖姿搜,靈堂內(nèi)的尸體忽然破棺而出寡润,到底是詐尸還是另有隱情,我是刑警寧澤舅柜,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布梭纹,位于F島的核電站,受9級(jí)特大地震影響业踢,放射性物質(zhì)發(fā)生泄漏栗柒。R本人自食惡果不足惜礁扮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一知举、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧太伊,春花似錦雇锡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至芳悲,卻和暖如春立肘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背名扛。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工谅年, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肮韧。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓融蹂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親弄企。 傳聞我的和親對(duì)象是個(gè)殘疾皇子超燃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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