Collection集合類和Map接口理解和對(duì)比

Github issues:https://github.com/littlejoyo/Blog/issues/

個(gè)人博客:https://littlejoyo.github.io/

微信公眾號(hào):Joyo說(shuō)

Collectionjava中最基本的集合接口晤郑,它存放在java.util包中,實(shí)現(xiàn)它的接口主要有List先改、Set掠抬、Queue欢摄,他們的實(shí)現(xiàn)細(xì)節(jié)有很大的不同,下面逐個(gè)介紹它們的主要作用和區(qū)別,還有Map不屬于Collection的內(nèi)容扶歪,Map的框架圖如下:

Collection集合框架圖

Collection框架圖
Map接口框架圖

List

  • 元素是有序的、可重復(fù)摄闸,可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制善镰。
  • 是一個(gè)有序容器,保持了每個(gè)元素的插入順序年枕,輸出的順序就是插入的順序炫欺。
  • 常用的實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector熏兄。

List接口的實(shí)現(xiàn)類

ArrayList

  • ArrayList底層使用了Object的數(shù)組作為容器去存儲(chǔ)數(shù)據(jù)
  • ArrayList 提供了使用索引的隨意訪問(wèn)數(shù)據(jù)
  • ArrayList 是線程非安全的品洛,效率較高,查詢速度高

LinkedList

  • LinkedList底層使用了鏈表的數(shù)據(jù)結(jié)構(gòu)
  • LinkedList隨機(jī)位置插入摩桶、刪除數(shù)據(jù)時(shí)比線性表快桥状,遍歷比線性表慢。
  • 相對(duì)于ArrayList硝清,LinkedList 對(duì)于經(jīng)常需要從 List 中添加或刪除元素的場(chǎng)合更為合適辅斟。
  • 和LinkedList一樣,ArrayList也是非同步的(unsynchronized)

Vector

  • Vector非常類似ArrayList芦拿,但是Vector是同步的砾肺,效率相對(duì)比較低
  • Vector的底層結(jié)構(gòu)也是數(shù)組,但是它們對(duì)數(shù)組的擴(kuò)容方式不同
  • 當(dāng)Vector或ArrayList中的元素超過(guò)它的初始大小時(shí),Vector會(huì)將它的容量翻倍,而ArrayList只增加50%的大小防嗡,這樣ArrayList就有利于節(jié)約內(nèi)存空間变汪。
    即Vector增長(zhǎng)原來(lái)的一倍,ArrayList增加原來(lái)的0.5倍蚁趁。

Stack棧繼承于Vector裙盾,棧的存儲(chǔ)特點(diǎn)是后進(jìn)先出,
它基于動(dòng)態(tài)數(shù)組實(shí)現(xiàn)的一個(gè)線程安全的棧,所以棧是線程安全的番官。

Set

  • 元素?zé)o序的庐完、不可重復(fù)。
  • 無(wú)序容器徘熔,你無(wú)法保證每個(gè)元素的存儲(chǔ)順序门躯,但是其中的TreeSet是特別的,TreeSet通過(guò) Comparator 或者 Comparable 維護(hù)了一個(gè)排序順序酷师。
  • 取出元素的方法只有迭代器和增強(qiáng)型for讶凉。
  • 只允許一個(gè) null 元素
  • Set 接口最流行的幾個(gè)實(shí)現(xiàn)類是 HashSet、LinkedHashSet 以及 TreeSet山孔。
  • Set和Map的底層聯(lián)系密切懂讯,可以說(shuō)想要了解Set直接先了解好Map即可
  • Set說(shuō)白了就是對(duì)Map的功能的限制

HashSet

  • HashSet底層實(shí)現(xiàn)其實(shí)是HashMap(看源碼可以知道)
  • HashSet實(shí)現(xiàn)了Set接口,它不允許集合中出現(xiàn)重復(fù)元素台颠。
  • 將對(duì)象存儲(chǔ)在HashSet之前褐望,要確保重寫(xiě)hashCode()方法和equals()方法,這樣才能比較對(duì)象的值是否相等串前,確保集合中沒(méi)有儲(chǔ)存相同的對(duì)象瘫里。
  • HashSet實(shí)現(xiàn)Set接口,由哈希表(實(shí)際上是一個(gè)HashMap實(shí)例)支持荡碾。
  • 在HashSet中谨读,元素都存到HashMap鍵值對(duì)的Key上面,而Value時(shí)有一個(gè)統(tǒng)一的值private static final Object PRESENT = new Object();
  • 當(dāng)有新值加入時(shí)玩荠,底層的HashMap會(huì)判斷Key值是否存在
  • 線程非安全的


    HashSet源碼

HashSet源碼介紹

public class HashSet<E>  
    extends AbstractSet<E>  
    implements Set<E>, Cloneable, java.io.Serializable  
{  
    static final long serialVersionUID = -5024744406713321676L;  

    // 底層使用HashMap來(lái)保存HashSet中所有元素漆腌。  
    private transient HashMap<E,Object> map;  

    // 定義一個(gè)虛擬的Object對(duì)象作為HashMap的value贼邓,將此對(duì)象定義為static final阶冈。  
    private static final Object PRESENT = new Object();  

    /** 
     * 默認(rèn)的無(wú)參構(gòu)造器,構(gòu)造一個(gè)空的HashSet塑径。 
     *  
     * 實(shí)際底層會(huì)初始化一個(gè)空的HashMap女坑,并使用默認(rèn)初始容量為16和加載因子0.75。 
     */  
    public HashSet() {  
    map = new HashMap<E,Object>();  
    }  

    /** 
     * 構(gòu)造一個(gè)包含指定collection中的元素的新set统舀。 
     * 
     * 實(shí)際底層使用默認(rèn)的加載因子0.75和足以包含指定 
     * collection中所有元素的初始容量來(lái)創(chuàng)建一個(gè)HashMap匆骗。 
     * @param c 其中的元素將存放在此set中的collection。 
     */  
    public HashSet(Collection<? extends E> c) {  
    map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));  
    addAll(c);  
    }  

    /** 
     * 以指定的initialCapacity和loadFactor構(gòu)造一個(gè)空的HashSet誉简。 
     * 
     * 實(shí)際底層以相應(yīng)的參數(shù)構(gòu)造一個(gè)空的HashMap碉就。 
     * @param initialCapacity 初始容量。 
     * @param loadFactor 加載因子闷串。 
     */  
    public HashSet(int initialCapacity, float loadFactor) {  
    map = new HashMap<E,Object>(initialCapacity, loadFactor);  
    }  

    /** 
     * 以指定的initialCapacity構(gòu)造一個(gè)空的HashSet瓮钥。 
     * 
     * 實(shí)際底層以相應(yīng)的參數(shù)及加載因子loadFactor為0.75構(gòu)造一個(gè)空的HashMap。 
     * @param initialCapacity 初始容量。 
     */  
    public HashSet(int initialCapacity) {  
    map = new HashMap<E,Object>(initialCapacity);  
    }  

    /** 
     * 以指定的initialCapacity和loadFactor構(gòu)造一個(gè)新的空鏈接哈希集合碉熄。 
     * 此構(gòu)造函數(shù)為包訪問(wèn)權(quán)限桨武,不對(duì)外公開(kāi),實(shí)際只是是對(duì)LinkedHashSet的支持锈津。 
     * 
     * 實(shí)際底層會(huì)以指定的參數(shù)構(gòu)造一個(gè)空LinkedHashMap實(shí)例來(lái)實(shí)現(xiàn)呀酸。 
     * @param initialCapacity 初始容量。 
     * @param loadFactor 加載因子琼梆。 
     * @param dummy 標(biāo)記性誉。 
     */  
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {  
    map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);  
    }  

    /** 
     * 返回對(duì)此set中元素進(jìn)行迭代的迭代器。返回元素的順序并不是特定的叮叹。 
     *  
     * 底層實(shí)際調(diào)用底層HashMap的keySet來(lái)返回所有的key艾栋。 
     * 可見(jiàn)HashSet中的元素,只是存放在了底層HashMap的key上蛉顽, 
     * value使用一個(gè)static final的Object對(duì)象標(biāo)識(shí)蝗砾。 
     * @return 對(duì)此set中元素進(jìn)行迭代的Iterator。 
     */  
    public Iterator<E> iterator() {  
    return map.keySet().iterator();  
    }  

    /** 
     * 返回此set中的元素的數(shù)量(set的容量)携冤。 
     * 
     * 底層實(shí)際調(diào)用HashMap的size()方法返回Entry的數(shù)量悼粮,就得到該Set中元素的個(gè)數(shù)。 
     * @return 此set中的元素的數(shù)量(set的容量)曾棕。 
     */  
    public int size() {  
    return map.size();  
    }  

    /** 
     * 如果此set不包含任何元素扣猫,則返回true。 
     * 
     * 底層實(shí)際調(diào)用HashMap的isEmpty()判斷該HashSet是否為空翘地。 
     * @return 如果此set不包含任何元素申尤,則返回true。 
     */  
    public boolean isEmpty() {  
    return map.isEmpty();  
    }  

    /** 
     * 如果此set包含指定元素衙耕,則返回true昧穿。 
     * 更確切地講,當(dāng)且僅當(dāng)此set包含一個(gè)滿足(o==null ? e==null : o.equals(e)) 
     * 的e元素時(shí)橙喘,返回true时鸵。 
     * 
     * 底層實(shí)際調(diào)用HashMap的containsKey判斷是否包含指定key。 
     * @param o 在此set中的存在已得到測(cè)試的元素厅瞎。 
     * @return 如果此set包含指定元素饰潜,則返回true。 
     */  
    public boolean contains(Object o) {  
    return map.containsKey(o);  
    }  

    /** 
     * 如果此set中尚未包含指定元素和簸,則添加指定元素彭雾。 
     * 更確切地講,如果此 set 沒(méi)有包含滿足(e==null ? e2==null : e.equals(e2)) 
     * 的元素e2锁保,則向此set 添加指定的元素e薯酝。 
     * 如果此set已包含該元素南誊,則該調(diào)用不更改set并返回false。 
     * 
     * 底層實(shí)際將將該元素作為key放入HashMap蜜托。 
     * 由于HashMap的put()方法添加key-value對(duì)時(shí)抄囚,當(dāng)新放入HashMap的Entry中key 
     * 與集合中原有Entry的key相同(hashCode()返回值相等,通過(guò)equals比較也返回true)橄务, 
     * 新添加的Entry的value會(huì)將覆蓋原來(lái)Entry的value幔托,但key不會(huì)有任何改變, 
     * 因此如果向HashSet中添加一個(gè)已經(jīng)存在的元素時(shí)蜂挪,新添加的集合元素將不會(huì)被放入HashMap中重挑, 
     * 原來(lái)的元素也不會(huì)有任何改變,這也就滿足了Set中元素不重復(fù)的特性棠涮。 
     * @param e 將添加到此set中的元素谬哀。 
     * @return 如果此set尚未包含指定元素,則返回true严肪。 
     */  
    public boolean add(E e) {  
    return map.put(e, PRESENT)==null;  
    }  

    /** 
     * 如果指定元素存在于此set中史煎,則將其移除。 
     * 更確切地講驳糯,如果此set包含一個(gè)滿足(o==null ? e==null : o.equals(e))的元素e篇梭, 
     * 則將其移除。如果此set已包含該元素酝枢,則返回true 
     * (或者:如果此set因調(diào)用而發(fā)生更改恬偷,則返回true)。(一旦調(diào)用返回帘睦,則此set不再包含該元素)袍患。 
     * 
     * 底層實(shí)際調(diào)用HashMap的remove方法刪除指定Entry。 
     * @param o 如果存在于此set中則需要將其移除的對(duì)象竣付。 
     * @return 如果set包含指定元素诡延,則返回true。 
     */  
    public boolean remove(Object o) {  
    return map.remove(o)==PRESENT;  
    }  

    /** 
     * 從此set中移除所有元素卑笨。此調(diào)用返回后孕暇,該set將為空仑撞。 
     * 
     * 底層實(shí)際調(diào)用HashMap的clear方法清空Entry中所有元素赤兴。 
     */  
    public void clear() {  
    map.clear();  
    }  

    /** 
     * 返回此HashSet實(shí)例的淺表副本:并沒(méi)有復(fù)制這些元素本身。 
     * 
     * 底層實(shí)際調(diào)用HashMap的clone()方法隧哮,獲取HashMap的淺表副本桶良,并設(shè)置到HashSet中。 
     */  
    public Object clone() {  
        try {  
            HashSet<E> newSet = (HashSet<E>) super.clone();  
            newSet.map = (HashMap<E, Object>) map.clone();  
            return newSet;  
        } catch (CloneNotSupportedException e) {  
            throw new InternalError();  
        }  
    }  
} 

LinkedHashSet

  • LinkedHashSet集合同樣是根據(jù)元素的hashCode值來(lái)決定元素的存儲(chǔ)位置
  • 它同時(shí)使用鏈表維護(hù)元素的次序沮翔。
  • LinkedHashSet在迭代訪問(wèn)Set中的全部元素時(shí)陨帆,性能比HashSet好,但是插入時(shí)性能稍微遜色于HashSet。
  • LinkedHashSet取出元素的順序和存入的順序一致
  • LinkedHashSet的底層實(shí)現(xiàn)是繼承了HashSet

TreeSet

  • TreeSet類型唯一可實(shí)現(xiàn)自動(dòng)排序的類型疲牵,即是取出的元素是經(jīng)過(guò)排序后輸出
  • TreeSet是SortedSet接口的唯一實(shí)現(xiàn)類承二,TreeSet可以確保集合元素處于排序狀態(tài)。
  • TreeSet判斷兩個(gè)對(duì)象不相等的方式是兩個(gè)對(duì)象通過(guò)equals方法返回false纲爸,或者通過(guò)CompareTo方法比較沒(méi)有返回0
  • TreeSet的底層實(shí)現(xiàn)是TreeMap的變形

HashSet亥鸠、LinkedHashSet、TreeSet取出元素的區(qū)別

Set中不能存放重復(fù)的代碼识啦,但是對(duì)于存取的方式它們也是存在著不同负蚊,這里做一個(gè)對(duì)比,關(guān)于取出元素的不同:

HashSet取出元素不能保證順序

 HashSet<String> set = new HashSet<String>();
        set.add("555");
        set.add("222");
        set.add("111");
        set.add("333");
        for (String s:set
             ) {
            System.out.println(s);
        }

輸出結(jié)果:
222
111
333
555

LinedHashSet取出元素和存入順序一致

LinkedHashSet<String> set = new LinkedHashSet<String>();
        set.add("555");
        set.add("222");
        set.add("111");
        set.add("333");
        for (String s:set
             ) {
            System.out.println(s);
        }

輸出結(jié)果:
555
222
111
333

TreeSet取出元素是經(jīng)過(guò)自然排序的

 TreeSet<String> set = new TreeSet<String>();
        set.add("555");
        set.add("222");
        set.add("111");
        set.add("333");
        for (String s:set
             ) {
            System.out.println(s);
        }

輸出結(jié)果:
111
222
333
555

Set存放對(duì)象颓哮,重寫(xiě)hashcode和equal判斷不同對(duì)象的實(shí)例

如果不對(duì)hashcode和equal進(jìn)行重寫(xiě)家妆,這兩個(gè)方法會(huì)照循Object基類的方法來(lái)進(jìn)行對(duì)象的判斷,但是這樣無(wú)法滿足我們自定義類是否相同的判斷冕茅。

不重寫(xiě)hashcode和equals

class Student {
    private String sid;//學(xué)生學(xué)號(hào)
    private String name;//學(xué)生姓名
    private String age;//學(xué)生年齡
}

public class Main {

    public static void main(String[] args) {


        Student s1 = new Student("111","小明","18");
        Student s2 = new Student("111","小明","18");
        System.out.println(s1.equals(s2));
        Set<Student> set = new HashSet<Student>();
        set.add(s1);
        set.add(s2);
        for (Student s:set
             ) {
            System.out.println(s.getName());
        }
    }

輸出結(jié)果:
false
小明
小明
事實(shí)上伤极,這兩個(gè)學(xué)生是同一個(gè)的,但是由于不重寫(xiě)所以按照Object的方法進(jìn)行判斷姨伤,s1和s2是兩個(gè)不同的對(duì)象
因此為了實(shí)現(xiàn)對(duì)自定義類進(jìn)行判斷就需要進(jìn)行對(duì)hashcode和equals的判斷

class Student {
    private String sid;//學(xué)生學(xué)號(hào)
    private String name;//學(xué)生姓名
    private String age;//學(xué)生年齡

  @Override
    public int hashCode() {
        Student stu = (Student) this;
        return sid.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Student)
        {
            Student stu = (Student) obj;
            return (sid.equals(stu.sid));
        }
        return super.equals(obj);
    }
}
public class Main {

    public static void main(String[] args) {


        Student s1 = new Student("111","小明","18");
        Student s2 = new Student("111","小明","18");
        System.out.println(s1.equals(s2));
        Set<Student> set = new HashSet<Student>();
        set.add(s1);
        set.add(s2);
        for (Student s:set
             ) {
            System.out.println(s.getName());
        }
    }

輸出結(jié)果:
true
小明

Map

  • 用于存儲(chǔ)健值對(duì)塑荒、根據(jù)鍵得到值、
  • 不允許鍵重復(fù)(重復(fù)了覆蓋了),但允許值重復(fù)
  • 實(shí)現(xiàn)類主要是HashMap姜挺、 HashTable 齿税、LinkedHashMap 和 TreeMap

HashTable和HashMap的對(duì)比

  • HashTable產(chǎn)生于JDK 1.1,而HashMap產(chǎn)生于JDK 1.2
  • HashTable的底層存儲(chǔ)是使用了數(shù)組+鏈表炊豪,1.7及之前HashMap使用數(shù)組+鏈表凌箕,1.8使用了數(shù)組+紅黑樹(shù)
  • Hashtable是線程安全的,HashMap是線程不安全的词渤,所以HashMap比Hashtable的性能高一點(diǎn)
  • Hashtable不允許使用null作為key和value牵舱;但HashMap可以使用null作為key或value。
  • 關(guān)于HashMap中缺虐,在jdk1.8之前是插入頭部的芜壁,在jdk1.8中是插入尾部的

LinkedHashMap

  • LinkedHashMap保存了記錄的插入順序高氮、在用Iterator遍歷LinkedHashMap時(shí)慧妄、先得到的記錄肯定是先插入的.也可以在構(gòu)造時(shí)用帶參數(shù)、按照應(yīng)用次數(shù)排序剪芍、在遍歷的時(shí)候會(huì)比HashMap慢
  • LinkedHashMap的遍歷速度只和實(shí)際數(shù)據(jù)有關(guān)塞淹、和容量無(wú)關(guān)、而HashMap的遍歷速度和他的容量有關(guān)

TreeMap

  • TreeMap實(shí)現(xiàn)SortMap接口罪裹、能夠把它保存的記錄根據(jù)鍵排序,默認(rèn)是按鍵值的升序排序
  • 當(dāng)用Iterator 遍歷TreeMap時(shí)饱普、得到的記錄是排過(guò)序的
  • TreeMap取出來(lái)的是排序后的鍵值對(duì)运挫、但如果您要按自然順序或自定義順序遍歷鍵、那么TreeMap會(huì)更好
  • LinkedHashMap 是HashMap的一個(gè)子類套耕、如果需要輸出的順序和輸入的相同,那么用LinkedHashMap可以實(shí)現(xiàn),它還可以按讀取順序來(lái)排列
  • TreeMap的底層實(shí)現(xiàn)是紅黑樹(shù)

HashMap谁帕、LinkedHashMap、TreeMap取出元素的情況和Set的實(shí)現(xiàn)類是一樣的冯袍,這里就不再舉例雇卷。

微信公眾號(hào)

掃一掃關(guān)注Joyo說(shuō)公眾號(hào),共同學(xué)習(xí)和研究開(kāi)發(fā)技術(shù)颠猴。

關(guān)注我
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末关划,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翘瓮,更是在濱河造成了極大的恐慌贮折,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件资盅,死亡現(xiàn)場(chǎng)離奇詭異调榄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)呵扛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)每庆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人今穿,你說(shuō)我怎么就攤上這事缤灵。” “怎么了蓝晒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵腮出,是天一觀的道長(zhǎng)佳晶。 經(jīng)常有香客問(wèn)我鄙皇,道長(zhǎng),這世上最難降的妖魔是什么强胰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任洛二,我火速辦了婚禮馋劈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晾嘶。我一直安慰自己妓雾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布变擒。 她就那樣靜靜地躺著君珠,像睡著了一般寝志。 火紅的嫁衣襯著肌膚如雪娇斑。 梳的紋絲不亂的頭發(fā)上策添,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音毫缆,去河邊找鬼唯竹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛苦丁,可吹牛的內(nèi)容都是我干的浸颓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼旺拉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼产上!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蛾狗,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晋涣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后沉桌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體谢鹊,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年留凭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了佃扼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蔼夜,死狀恐怖兼耀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情求冷,我是刑警寧澤翠订,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站遵倦,受9級(jí)特大地震影響尽超,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜梧躺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一似谁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掠哥,春花似錦巩踏、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至禁舷,卻和暖如春彪杉,著一層夾襖步出監(jiān)牢的瞬間毅往,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工派近, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留攀唯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓渴丸,卻偏偏與公主長(zhǎng)得像侯嘀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谱轨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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