Java語(yǔ)言基礎(chǔ)四(集合篇)

集合的概述

集合的由來(lái)

在介紹集合之前虽惭,應(yīng)先了解java中對(duì)于不同的數(shù)據(jù)類型應(yīng)該用什么來(lái)記錄。

  • 當(dāng)需要在Java程序中記錄單個(gè)數(shù)據(jù)內(nèi)容時(shí)蛇尚,則聲明一個(gè)變量芽唇。

  • 當(dāng)需要在Java程序中記錄多個(gè)類型相同的數(shù)據(jù)內(nèi)容時(shí),聲明一個(gè)一維數(shù)組佣蓉。

  • 當(dāng)需要在Java程序中記錄多個(gè)類型不同的數(shù)據(jù)內(nèi)容時(shí),則創(chuàng)建一個(gè)對(duì)象亲雪。

  • 當(dāng)需要在Java程序中記錄多個(gè)類型相同的對(duì)象數(shù)據(jù)時(shí)勇凭,創(chuàng)建一個(gè)對(duì)象數(shù)組。

  • 當(dāng)需要在Java程序中記錄多個(gè)類型不同的對(duì)象數(shù)據(jù)時(shí)义辕,則準(zhǔn)備一個(gè)集合虾标。

集合的框架結(jié)構(gòu)**

Java中集合框架頂層框架是:java.util.Collection集合 和 java.util.Map集合。

其中Collection集合中存取元素的基本單位是:?jiǎn)蝹€(gè)元素灌砖。

其中Map集合中存取元素的基本單位是:?jiǎn)螌?duì)元素璧函。

image

Collection集合

概念

Collection接口它是List接口、Queue 接口以及Set接口的父接口基显,因此該接口里定義的方法既可用于操作List集合蘸吓,也可用于操作Queue集合和Set集合。

注意:Collections類是一個(gè)工具類库继,該類主要提供操作集合的一些方法。

Collection接口中常用的方法:
方法聲明 功能介紹
boolean add(E e) 向集合中添加對(duì)象(單個(gè)元素)窜醉;
boolean addAll(Collection<? extends E>c) 用于將參數(shù)指定集合c中的所有元素添加到當(dāng)前集合中(一個(gè)一個(gè)添加)宪萄;
boolean contains(Object o) 判斷是否包含指定對(duì)象;
boolean containsAll(Collection<?> c) 判斷是否包含參數(shù)指定的所有對(duì)象榨惰;
boolean retainAll(Collection<?> c) 保留當(dāng)前集合中存在且參數(shù)集合中存在的所有對(duì)象拜英;
boolean remove(Object o) 從集合中刪除對(duì)象(刪除整體對(duì)象);
boolean removeAll(Collection<?> c) 從集合中刪除參數(shù)指定的所有對(duì)象(一個(gè)一個(gè)元素刪)琅催;
void clear() 清空集合居凶;
int size() 返回包含對(duì)象的個(gè)數(shù);
boolean isEmpty() 判斷是否為空藤抡;
boolean equals(Object o) 判斷是否相等排监;
int hashCode() 獲取當(dāng)前集合的哈希碼值;
Object[] toArray() 將集合轉(zhuǎn)換為數(shù)組杰捂;
Iterator iterator() 獲取當(dāng)前集合的迭代器舆床;

Iterator接口(迭代器)

基本概念

-- java.util.Iterator接口主要用于描述迭代器對(duì)象,可以遍歷Collection集合中的所有元素。
-- java.util.Collection接口繼承Iterator接口挨队,因此所有實(shí)現(xiàn)Collection接口的實(shí)現(xiàn)類都可以使用該迭代器對(duì)象谷暮。

遍歷集合的方式
public class CollectionTest {
 
    public static void main(String[] args) {
 
        // 準(zhǔn)備一個(gè)Collection集合并放入元素后打印
        Collection c1 = new ArrayList();
        c1.add("one");
        c1.add(2);
        c1.add(new Person("zhangsan", 30));//要先封裝一個(gè)Person類


        // 遍歷方式一: 自動(dòng)調(diào)用toString方法   String類型的整體
        System.out.println("c1 = " + c1); // [one, 2, Person{name='zhangsan', age=30}]
 
        System.out.println("------------------------------------------------");
 
 
        // 遍歷方式二:使用迭代器來(lái)遍歷集合中的所有元素  更加靈活
 
        //  獲取當(dāng)前集合中的迭代器對(duì)象
        Iterator iterator1 = c1.iterator();
 
        //   判斷是否有元素可以訪問
        while (iterator1.hasNext()) {
            // 取出一個(gè)元素并指向下一個(gè)
            System.out.println("獲取到的元素是:" + iterator1.next());
        }
 

        /** 
          遍歷方式三: 使用for each結(jié)構(gòu)實(shí)現(xiàn)集合和數(shù)組中元素的遍歷  代碼簡(jiǎn)單且方法靈活
           格式:for(元素類型 變量名 : 數(shù)組/集合名稱) {
                    循環(huán)體; 
                  }
          
          該方式其實(shí)是迭代器的簡(jiǎn)化版
         */
        for (Object obj : c1) {
            System.out.println("取出來(lái)的元素是:" + obj);
        }
    }
}

那如何在遍歷的過(guò)程中進(jìn)行元素的刪除呢?
-- 可以用到迭代器提供的remove()方法

// 借助上面代碼中的集合c1來(lái)實(shí)現(xiàn)
// 3.不斷地去獲取集合中的元素并判斷盛垦,當(dāng)元素值為"one"時(shí)則刪除該元素
        iterator1 = c1.iterator(); //重置迭代器
        while (iterator1.hasNext()) {
            Object obj = iterator1.next();
            if("one".equals(obj)) {
                iterator1.remove();  //使用迭代器的remove方法刪除元素
                ConcurrentModificationException并發(fā)修改異常
            }
        }
        System.out.println("刪除后集合中的元素有:" + c1); // [2, Person{name='zhangsan', age=30}]

List集合

java.util.List集合是Collection集合的子集合湿弦,該集合中允許有重復(fù)的元素并且有先后放入次序。

  • 該集合的主要實(shí)現(xiàn)類有:ArrayList類腾夯、LinkedList類颊埃、Stack類、Vector類蝶俱。

  • 其中ArrayList類的底層是采用動(dòng)態(tài)數(shù)組進(jìn)行數(shù)據(jù)管理的班利,支持下標(biāo)訪問,增刪元素不方便榨呆。

  • 其中LinkedList類的底層是采用雙向鏈表進(jìn)行數(shù)據(jù)管理的罗标,訪問不方便,增刪元素方便积蜻〈掣睿可以認(rèn)為ArrayList和LinkedList的方法在邏輯上完全一樣,只是在性能上有一定的差別

  • ArrayList 更適合于訪問而LinkedList更適合于插入和刪除竿拆;在性能要求不是特別苛刻的情 形下可以忽略這個(gè)差別宙拉。

  • 其中Stack類的底層是采用動(dòng)態(tài)數(shù)組進(jìn)行數(shù)據(jù)管理的,該類主要用于描述一種具有后進(jìn)先 出特征的數(shù)據(jù)結(jié)構(gòu)丙笋,叫做棧(last in first out LIFO)鼓黔。

  • 其中Vector類的底層是采用動(dòng)態(tài)數(shù)組進(jìn)行數(shù)據(jù)管理的,該類與ArrayList類相比屬于線程安全的類不见,效率比較低澳化,以后開發(fā)中基本不用。

常用的方法:
方法聲明 功能介紹
void add(int index, E element) 向集合中指定位置添加元素
boolean addAll(int index, Collection<? extends E> c) 向集合中添加所有元素
E get(int index) 從集合中獲取指定位置元素
int indexOf(Object o) 查找參數(shù)指定的對(duì)象
int lastIndexOf(Object o) 反向查找參數(shù)指定的對(duì)象
E set(int index, E element) 修改指定位置的元素
E remove(int index) 刪除指定位置的元素
List subList(int fromIndex, int toIndex) 用于獲取子List(子集合和當(dāng)前集合共用同一塊內(nèi)存空間)

注意:使用工具類Arrays.asList()可以將數(shù)組轉(zhuǎn)換成集合稳吮,返回的對(duì)象是一個(gè)Arrays內(nèi)部類缎谷,使用該方法時(shí)注意不能使用修改集合的相關(guān)方法否則會(huì)拋出異常。Arrays.asList體現(xiàn)的是適配器模式灶似,只是轉(zhuǎn)換接口列林,后臺(tái)的數(shù)據(jù)依然是數(shù)組。

Queue集合

java.util.Queue集合是Collection集合的子集合酪惭,與List集合屬于平級(jí)關(guān)系希痴。

  • 該集合的主要用于描述具有先進(jìn)先出特征的數(shù)據(jù)結(jié)構(gòu),叫做隊(duì)列(first in first out FIFO)春感。
  • 該集合的主要實(shí)現(xiàn)類是LinkedList類砌创,因?yàn)樵擃愒谠鰟h方面比較有優(yōu)勢(shì)虏缸。
常用的方法:
方法聲明 功能介紹
boolean offer(E e) 將一個(gè)對(duì)象添加至隊(duì)尾,若添加成功則返回true
E poll() 從隊(duì)首刪除并返回一個(gè)元素
E peek() 返回隊(duì)首的元素(但并不刪除)

Set集合

java.util.Set集合是Collection集合的子集合嫩实,與List集合平級(jí)刽辙。

  • 該集合中元素沒有先后放入次序,且不允許重復(fù)甲献。

  • 該集合的主要實(shí)現(xiàn)類是:HashSet類 和TreeSet類以及LinkedHashSet類宰缤。

  • 其中HashSet類的底層是采用哈希表進(jìn)行數(shù)據(jù)管理的。

  • 其中TreeSet類的底層是采用紅黑樹進(jìn)行數(shù)據(jù)管理的晃洒。

  • 其中LinkedHashSet類與HashSet類的不同之處在于內(nèi)部維護(hù)了一個(gè)雙向鏈表慨灭,鏈表中記錄了元素的迭代順序,也就是元素插入集合中的先后順序球及,因此便于迭代氧骤。

注意:該集合的常用方法參考Collection集合。

元素放入HashSet集合的原理:
  • 使用元素調(diào)用hashCode方法獲取對(duì)應(yīng)的哈希碼值桶略,再由某種哈希算法計(jì)算出該元素在數(shù)組中的索引位置语淘。

  • 若該位置沒有元素诲宇,則將該元素直接放入即可际歼。

  • 若該位置有元素,則使用新元素與已有元素依次比較哈希值姑蓝,若哈希值不相同鹅心,則將該元素直接放入。

  • 若新元素與已有元素的哈希值相同纺荧,則使用新元素調(diào)用equals方法與已有元素依次比較旭愧。

  • 若相等則添加元素失敗,否則將元素直接放入即可宙暇。

-- 那么問題來(lái)了输枯,為什么要求重寫equals方法后要重寫hashCode方法呢?
答:當(dāng)兩個(gè)元素調(diào)用equals方法相等時(shí)證明這兩個(gè)元素相同占贫,重寫hashCode方法后保證這兩個(gè)元 素得到的哈希碼值相同桃熄,由同一個(gè)哈希算法生成的索引位置相同,此時(shí)只需要與該索引位置已有元素比較即可型奥,從而提高效率并避免重復(fù)元素的出現(xiàn)瞳收。

TreeSet集合

二叉樹主要指每個(gè)節(jié)點(diǎn)最多只有兩個(gè)子節(jié)點(diǎn)的樹形結(jié)構(gòu)。

滿足以下3個(gè)特征的二叉樹叫做有序二叉樹:

a.左子樹中的任意節(jié)點(diǎn)元素都小于根節(jié)點(diǎn)元素值厢汹;

b.右子樹中的任意節(jié)點(diǎn)元素都大于根節(jié)點(diǎn)元素值螟深;

c.左子樹和右子樹的內(nèi)部也遵守上述規(guī)則;

由于TreeSet集合的底層采用紅黑樹進(jìn)行數(shù)據(jù)的管理烫葬,當(dāng)有新元素插入到TreeSet集合時(shí)界弧,需要使用新元素與集合中已有的元素依次比較來(lái)確定新元素的合理位置凡蜻。

比較元素大小的規(guī)則有兩種方式:

使用元素的自然排序規(guī)則進(jìn)行比較并排序,讓元素類型實(shí)現(xiàn)java.lang.Comparable接口夹纫;

使用比較器規(guī)則進(jìn)行比較并排序咽瓷,構(gòu)造TreeSet集合時(shí)傳入java.util.Comparator接口;

自然排序的規(guī)則比較單一舰讹,而比較器的規(guī)則比較多元化茅姜,而且比較器優(yōu)先于自然排序;


Map集合

概念

-- java.util.Map<K,V>集合中存取元素的基本單位是:?jiǎn)螌?duì)元素月匣,其中類型參數(shù)如下:

  • K - 此映射所維護(hù)的鍵(Key)的類型钻洒,相當(dāng)于目錄。
  • V - 映射值(Value)的類型锄开,相當(dāng)于內(nèi)容素标。
  • 該集合中key是不允許重復(fù)的,而且一個(gè)key只能對(duì)應(yīng)一個(gè)value萍悴。

  • 該集合的主要實(shí)現(xiàn)類有:HashMap類头遭、TreeMap類、LinkedHashMap類癣诱、Hashtable類计维、Properties類。

  • 其中HashMap類的底層是采用哈希表進(jìn)行數(shù)據(jù)管理的。

  • 其中TreeMap類的底層是采用紅黑樹進(jìn)行數(shù)據(jù)管理的。

  • 其中LinkedHashMap類與HashMap類的不同之處在于內(nèi)部維護(hù)了一個(gè)雙向鏈表习瑰,鏈表中記錄了元素的迭代順序,也就是元素插入集合中的先后順序欠母,因此便于迭代。

  • 其中Hashtable類是古老的Map實(shí)現(xiàn)類吆寨,與HashMap類相比屬于線程安全的類赏淌,且不允許null作為key或者value的數(shù)值。

  • 其中Properties類是Hashtable類的子類啄清,該對(duì)象用于處理屬性文件六水,key和value都是String類型的。

  • Map集合是面向查詢優(yōu)化的數(shù)據(jù)結(jié)構(gòu), 在大數(shù)據(jù)量情況下有著優(yōu)良的查詢性能盒延。

  • 經(jīng)常用于根據(jù)key檢索value的業(yè)務(wù)場(chǎng)景缩擂。

常用的方法:
方法聲明 功能介紹
V put(K key, V value) 將Key-Value對(duì)存入Map,若集合中已經(jīng)包含該Key添寺,則替換該Key所對(duì)應(yīng)的Value胯盯,返回值為該Key原來(lái)所對(duì)應(yīng)的Value,若沒有則返回null;
V get(Object key) 返回與參數(shù)Key所對(duì)應(yīng)的Value對(duì)象计露,如果不存在則返回null
boolean containsKey (Object key) 判斷集合中是否包含指定的Key
boolean containsValue (Object value) 判斷集合中是否包含指定的Value
V remove(Object key) 根據(jù)參數(shù)指定的key進(jìn)行刪除
Set keySet() 返回此映射中包含的鍵的Set視圖
Collection values() 返回此映射中包含的值的Set視圖
Set<Map.Entry<K,V>>entrySet() 返回此映射中包含的映射的Set視圖

這里就演示添加和遍歷的操作:

// 1.準(zhǔn)備一個(gè)Map集合
Map<String, String> m1 = new HashMap<>();
 
// 2.向集合中添加元素并打印
String str1 = m1.put("1", "one");
System.out.println("原來(lái)的value數(shù)值為:" + str1); // null
System.out.println("m1 = " + m1); // {1=one}
 
str1 = m1.put("2", "two");
System.out.println("原來(lái)的value數(shù)值為:" + str1); // null
System.out.println("m1 = " + m1); // {1=one, 2=two}
 
str1 = m1.put("3", "three");
System.out.println("原來(lái)的value數(shù)值為:" + str1); // null
System.out.println("m1 = " + m1); // {1=one, 2=two, 3=three}
 
// 實(shí)現(xiàn)了修改的功能
str1 = m1.put("1", "eleven");
System.out.println("原來(lái)的value數(shù)值為:" + str1); // one
System.out.println("m1 = " + m1); // {1=eleven, 2=two, 3=three}
 
 
/**
  Map集合的三種遍歷方式
*/
 
// 方式一:獲取Map集合中所有的key并組成Set視圖
Set<String> s1 = m1.keySet();
// 遍歷所有的key
for (String ts : s1) {
     System.out.println(ts + "=" + m1.get(ts));
}
 
// 方式二:獲取Map集合中所有的Value并組成Collection視圖
Collection<String> co = m1.values();
for (String ts : co) {
     System.out.println("ts = " + ts);
}
 
// 方式三:獲取Map集合中所有的鍵值對(duì)并組成Set視圖
Set<Map.Entry<String, String>> entries = m1.entrySet();
for (Map.Entry<String, String> me : entries) {
     System.out.println(me);
}
元素放入HashMap集合的原理:
  • 使用元素的key調(diào)用hashCode方法獲取對(duì)應(yīng)的哈希碼值博脑,再由某種哈希算法計(jì)算在數(shù)組中的索引位置憎乙。

  • 若該位置沒有元素,則將該鍵值對(duì)直接放入即可叉趣。

  • 若該位置有元素泞边,則使用key與已有元素依次比較哈希值,若哈希值不相同疗杉,則將該元素直接放入阵谚。

  • 若key與已有元素的哈希值相同,則使用key調(diào)用equals方法與已有元素依次比較烟具。

  • 若相等則將對(duì)應(yīng)的value修改梢什,否則將鍵值對(duì)直接放入即可。

相關(guān)的常量:

DEFAULT_INITIAL_CAPACITY : HashMap的默認(rèn)容量是:16朝聋。

DEFAULT_LOAD_FACTOR:HashMap的默認(rèn)加載因子是:0.75嗡午。

threshold:擴(kuò)容的臨界值,該數(shù)值為:容量*填充因子冀痕,也就是:12荔睹。

TREEIFY_THRESHOLD:若Bucket中鏈表長(zhǎng)度大于該默認(rèn)值則轉(zhuǎn)化為紅黑樹存儲(chǔ),該數(shù)值是:8言蛇。

MIN_TREEIFY_CAPACITY:桶中的Node被樹化時(shí)最小的hash表容量僻他,該數(shù)值是:64。


Collections工具類類

概念

-- java.util.Collections類主要提供了對(duì)集合操作或者返回集合的靜態(tài)方法猜极。

注意:Collection是List和Set的父接口中姜,而Collections是一個(gè)工具類消玄。

常用的方法
方法聲明 功能介紹
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 根據(jù)元素的自然順序返回給定集合的最大元素
static T max(Collection<? extends T> coll, Comparator<?super T> comp) 根據(jù)指定比較器引發(fā)的順序返回給定集合的最大元素
static <T extends Object & Comparable<?super T>> T min(Collection<? extends T> coll) 根據(jù)元素的自然順序返回給定集合的最小元素
static T min(Collection<? extends T> coll, Comparator<?super T> comp) 根據(jù)指定比較器引發(fā)的順序返回給定集合的最小元素
static void copy(List<? super T> dest, List<? extends T>src) 將一個(gè)列表中的所有元素復(fù)制到另一個(gè)列表中
static void reverse(List<?> list) 反轉(zhuǎn)指定列表中元素的順序
static void shuffle(List<?> list) 使用默認(rèn)的隨機(jī)源隨機(jī)置換指定的列表
static <T extends Comparable<? super T>> void sort(List list) 根據(jù)其元素的自然順序?qū)⒅付斜戆瓷蚺判?/td>
static void sort(List list, Comparator<? super T> c) 根據(jù)指定比較器指定的順序?qū)χ付斜磉M(jìn)行排序
static void swap(List<?> list, int i, int j) 交換指定列表中指定位置的元素
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末跟伏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翩瓜,更是在濱河造成了極大的恐慌受扳,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兔跌,死亡現(xiàn)場(chǎng)離奇詭異勘高,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)坟桅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門华望,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人仅乓,你說(shuō)我怎么就攤上這事赖舟。” “怎么了夸楣?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵宾抓,是天一觀的道長(zhǎng)子漩。 經(jīng)常有香客問我,道長(zhǎng)石洗,這世上最難降的妖魔是什么幢泼? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮讲衫,結(jié)果婚禮上缕棵,老公的妹妹穿的比我還像新娘。我一直安慰自己涉兽,他們只是感情好挥吵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著花椭,像睡著了一般忽匈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上矿辽,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天丹允,我揣著相機(jī)與錄音,去河邊找鬼袋倔。 笑死雕蔽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宾娜。 我是一名探鬼主播批狐,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼前塔!你這毒婦竟也來(lái)了嚣艇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤华弓,失蹤者是張志新(化名)和其女友劉穎食零,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寂屏,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贰谣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了迁霎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吱抚。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖考廉,靈堂內(nèi)的尸體忽然破棺而出秘豹,到底是詐尸還是另有隱情,我是刑警寧澤芝此,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布憋肖,位于F島的核電站因痛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岸更。R本人自食惡果不足惜鸵膏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怎炊。 院中可真熱鬧谭企,春花似錦、人聲如沸评肆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瓜挽。三九已至盹廷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間久橙,已是汗流浹背俄占。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淆衷,地道東北人缸榄。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像祝拯,于是被迫代替她去往敵國(guó)和親甚带。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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