Java編程的利器:Pair和Triple無縫解決多值返回問題钳榨,助力編寫高效代碼

在實(shí)際編碼中,經(jīng)常會遇到一個(gè)方法需要返回多個(gè)值的情況纽门,你編寫一個(gè)方法薛耻,需要同時(shí)返回某個(gè)操作的結(jié)果和一些相關(guān)的附加信息基跑。使用傳統(tǒng)的方式澜薄,你可能需要?jiǎng)?chuàng)建一個(gè)包含這些信息的自定義類或者使用集合(如 Map)來存儲這些值。然而,這往往使得代碼變得臃腫吃媒,而且對于調(diào)用方來說,理解和提取這些值可能會顯得有些繁瑣死陆。

這時(shí)使用org.apache.commons.lang3.tuple下的PairTriple 及其子類是一種非常便捷的解決方案肴焊。這些類提供了一種清晰、簡單的方式來組織和傳遞多個(gè)相關(guān)聯(lián)的值倒淫,使得代碼更加直觀和易于理解伙菊。

使用 PairTriple 就能輕松解決這個(gè)問題。你可以在一個(gè)方法中返回一個(gè) PairTriple 對象敌土,其中包含你想要傳遞的多個(gè)值镜硕。這樣,你可以清晰地表示這些值之間的關(guān)系返干,而且調(diào)用方可以輕松地訪問和使用這些值兴枯,而無需繁瑣的解包過程。

在接下來的部分矩欠,我們將深入研究如何在這類場景中使用 PairTriple 及其子類财剖,以及它們?nèi)绾魏喕覀冊诰幋a中常遇到的多值返回問題。

引入依賴:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

Pair 類介紹

Pair 類是org.apache.commons.lang3庫提供的一個(gè)簡單的鍵值對容器癌淮,用于表示兩個(gè)相關(guān)聯(lián)的值躺坟。其主要作用是將兩個(gè)值組織在一起,提供一種便捷的方式進(jìn)行傳遞和處理乳蓄。

首先我們來看一下Pair的源碼:

/**
 * 抽象類咪橙,表示簡單的鍵值對。
 * 實(shí)現(xiàn)了 Map.Entry 接口虚倒,支持在各種集合中使用美侦。
 * 實(shí)現(xiàn)了 Comparable 接口,用于比較兩個(gè) Pair 對象的大小魂奥。
 * 可序列化菠剩,支持對象的序列化和反序列化。
 *
 * @param <L> 左值的類型
 * @param <R> 右值的類型
 */
public abstract class Pair<L, R> implements Map.Entry<L, R>, Comparable<Pair<L, R>>, Serializable {

    private static final long serialVersionUID = 4954918890077093841L;

    // 空數(shù)組耻煤,用于表示空的 Pair 對象數(shù)組
    public static final Pair<?, ?>[] EMPTY_ARRAY = new PairAdapter[0];

    /**
     * 返回一個(gè)空的 Pair 數(shù)組具壮。
     *
     * @return 空的 Pair 數(shù)組
     */
    public static <L, R> Pair<L, R>[] emptyArray() {
        return (Pair[]) EMPTY_ARRAY;
    }

    /**
     * 靜態(tài)工廠方法,創(chuàng)建一個(gè)新的 ImmutablePair 對象哈蝇,表示給定的左右值的鍵值對嘴办。
     *
     * @param left  左值
     * @param right 右值
     * @param <L>   左值的類型
     * @param <R>   右值的類型
     * @return ImmutablePair 對象
     */
    public static <L, R> Pair<L, R> of(L left, R right) {
        return ImmutablePair.of(left, right);
    }

    /**
     * 靜態(tài)工廠方法,創(chuàng)建一個(gè)新的 ImmutablePair 對象买鸽,表示給定 Map.Entry 對象的鍵值對涧郊。
     *
     * @param pair Map.Entry 對象
     * @param <L>  左值的類型
     * @param <R>  右值的類型
     * @return ImmutablePair 對象
     */
    public static <L, R> Pair<L, R> of(Map.Entry<L, R> pair) {
        return ImmutablePair.of(pair);
    }

    /**
     * 返回左值,實(shí)現(xiàn)了 Map.Entry 接口眼五。
     *
     * @return 左值
     */
    public final L getKey() {
        return this.getLeft();
    }

    /**
     * 抽象方法妆艘,由子類實(shí)現(xiàn)彤灶,用于獲取左值。
     *
     * @return 左值
     */
    public abstract L getLeft();

    /**
     * 抽象方法批旺,由子類實(shí)現(xiàn)幌陕,用于獲取右值。
     *
     * @return 右值
     */
    public abstract R getRight();

    /**
     * 返回右值汽煮,實(shí)現(xiàn)了 Map.Entry 接口搏熄。
     *
     * @return 右值
     */
    public R getValue() {
        return this.getRight();
    }
}

Pair類是一個(gè)抽象類,它有兩個(gè)子類ImmutablePairMutablePair暇赤。接下來我們介紹一下這兩個(gè)子類心例,也是我們要使用的兩個(gè)類。

MutablePair

MutablePair是一個(gè)可變的鞋囊。它允許在創(chuàng)建后動(dòng)態(tài)修改鍵和值止后,提供了更大的靈活性。但是它是線程不安全的溜腐。
我們可以根據(jù)它提供的幾個(gè)靜態(tài)方法或者它的構(gòu)造器去構(gòu)造一個(gè)MutablePair:

// 靜態(tài)工廠方法译株,返回一個(gè)空的 MutablePair
public static <L, R> MutablePair<L, R>[] emptyArray();

// 靜態(tài)工廠方法,傳入給定的左右值的鍵值對挺益,創(chuàng)建并返回一個(gè)MutablePair 對象
public static <L, R> MutablePair<L, R> of(L left, R right);

// 靜態(tài)工廠方法歉糜,傳入給定 Map.Entry 對象的鍵值對,創(chuàng)建并返回一個(gè)新的MutablePair 對象
public static <L, R> MutablePair<L, R> of(Map.Entry<L, R> pair);

// 無參構(gòu)造器
public MutablePair()

// 指定左右值的鍵值對的構(gòu)造器
public MutablePair(L left, R right)

我們可以根據(jù)它的幾個(gè)方法修改鍵和值:

// 修改左值
public void setLeft(L left);

// 修改右值
public void setRight(R right);

// 修改新的右值望众,并返回之前的右值匪补。
public R setValue(R value);

我們可以根據(jù)它的幾個(gè)方法獲取鍵和值:

// 獲取左值
public L getLeft();

// Pair中的方法  獲取左值
public final L getKey();

// 獲取右值
public R getRight();

// Pair中的方法  獲取右值 
public R getValue();

當(dāng)然我們看到它的left以及right都是public的。所以我們也可以直接取值黍檩,不用使用它的get方法。

ImmutablePair

ImmutablePairPair的一個(gè)不可變的子類始锚。它在創(chuàng)建完成之后刽酱,不允許改變鍵和值。它是線程安全的瞧捌。

我們可以看一下它如何進(jìn)行構(gòu)造的:

// 靜態(tài)工廠方法棵里,返回一個(gè)空的 ImmutablePair 數(shù)組。
public static <L, R> ImmutablePair<L, R>[] emptyArray();

// 靜態(tài)工廠方法姐呐,返回一個(gè)包含 null 左值和 null 右值的 ImmutablePair 對象殿怜,表示空值。
public static <L, R> ImmutablePair<L, R> nullPair();

// 靜態(tài)工廠方法曙砂,返回一個(gè)包含指定左值和 null 右值的 ImmutablePair 對象头谜。
public static <L, R> Pair<L, R> left(L left);

// 靜態(tài)工廠方法,返回一個(gè)包含 null 左值和指定右值的 ImmutablePair 對象鸠澈。
public static <L, R> Pair<L, R> right(R right);

// 靜態(tài)工廠方法柱告,創(chuàng)建并返回一個(gè)新的 ImmutablePair 對象截驮,表示給定的左右值的鍵值對。
public static <L, R> ImmutablePair<L, R> of(L left, R right);

// 靜態(tài)工廠方法际度,創(chuàng)建并返回一個(gè)新的 ImmutablePair 對象葵袭,表示給定 Map.Entry 對象的鍵值對。
public static <L, R> ImmutablePair<L, R> of(Map.Entry<L, R> pair);

// 有參構(gòu)造器 傳入給定的左右值的鍵值對乖菱。
public ImmutablePair(L left, R right);

我們可以根據(jù)它的幾個(gè)方法獲取鍵和值:

// 獲取左值
public L getLeft();

// Pair中的方法  獲取左值
public final L getKey();

// 獲取右值
public R getRight();

// Pair中的方法  獲取右值 
public R getValue();

當(dāng)然我們看到它的left以及right都是public的坡锡。所以我們也可以直接取值,不用使用它的get方法窒所。

那我們再看一下為什么ImmutablePair是不可變的鹉勒,并且是線程安全的。
首先我們看一下它的左值以及右值都是final的墩新,不可更改的贸弥。并且調(diào)用它的setValue會拋出UnsupportedOperationException

public final L left;  
public final R right;

public R setValue(R value) {  
    throw new UnsupportedOperationException();  
}

類中的 leftright 成員變量被聲明為 final海渊,這意味著它們在對象創(chuàng)建后不能被修改绵疲,確保了線程安全性。ImmutablePair 被設(shè)計(jì)為不可變的鍵值對類臣疑,即一旦創(chuàng)建盔憨,其內(nèi)容不可更改。這確保了在多線程環(huán)境中讯沈,不會有并發(fā)修改的問題郁岩。

使用示例

/**  
 * 返回MutablePair  
 * @param userDO  
 * @return  
 */  
private static MutablePair<String, Integer> handleUserInfo1(UserDO userDO){  
    return MutablePair.of(userDO.getUserId(), userDO.getAge());  
}  
  
/**  
 * 返回ImmutablePair  
 * @param userDO  
 * @return  
 */  
private static ImmutablePair<String, Integer> handleUserInfo2(UserDO userDO){  
    return ImmutablePair.of(userDO.getUserId(), userDO.getAge());  
}  
  
public static void main(String[] args) {  
    UserDO userDO = new UserDO();  
    userDO.setUserId("coderacademy");  
    userDO.setAge(35);  
  
    MutablePair<String, Integer> mutablePair = handleUserInfo1(userDO);  
    System.out.println(mutablePair.getLeft()+" MutablePair修改前:"+ mutablePair.right);  
    mutablePair.setRight(40);  
    System.out.println(mutablePair.getLeft()+" MutablePair修改后:"+ mutablePair.right);  
  
    ImmutablePair<String, Integer> immutablePair = handleUserInfo2(userDO);  
    System.out.println(mutablePair.getLeft()+" ImmutablePair修改前:"+ mutablePair.right);  
    immutablePair.setValue(50);  
    System.out.println(mutablePair.getLeft()+" ImmutablePair修改后:"+ mutablePair.right);  
}

執(zhí)行結(jié)果,我們發(fā)現(xiàn)ImmutablePair在修改value時(shí)報(bào)錯(cuò):

Pair 類及其子類 ImmutablePairMutablePair 是用于表示鍵值對的實(shí)用工具類缺狠。ImmutablePair 是不可變的问慎、線程安全的,適用于安全共享挤茄;MutablePair 允許動(dòng)態(tài)修改值如叼,但不具備線程安全性,適用于單線程環(huán)境穷劈。它們在方法返回多個(gè)值時(shí)提供了簡便的解決方案笼恰,提高了代碼的靈活性。

Triple介紹

Triple 是一個(gè)用于表示三元組的抽象類歇终。三元組是由三個(gè)元素組成的有序集合社证,其中每個(gè)元素都有特定的位置,分別稱為左值(Left)评凝、中間值(Middle)和右值(Right)追葡。Triple 類提供了一種便捷的方式來組織和處理這種具有固定順序的數(shù)據(jù)。可以在不創(chuàng)建專門類的情況下輕松返回三個(gè)值辽俗。通過 Triple疾渣,開發(fā)者可以更方便地處理包含三個(gè)元素的數(shù)據(jù),減少了創(chuàng)建和維護(hù)多個(gè)變量的復(fù)雜性崖飘,使代碼更加簡潔榴捡。

我們來看一下Triple的源碼:

/**
 * 表示包含三個(gè)元素的三元組的抽象類 Triple。
 *
 * 該類是一個(gè)抽象實(shí)現(xiàn)朱浴,定義了基本的 API吊圾,將元素分別稱為 'left'、'middle' 和 'right'翰蠢。
 *
 * 子類的實(shí)現(xiàn)可以是可變的或不可變的项乒。對存儲的對象類型沒有限制。
 * Triple 對象的可變性取決于其中存儲的對象是否是可變的梁沧。如果存儲的是可變對象檀何,那么 Triple 本身也就變得可變,因?yàn)榇鎯Φ膶ο鬆顟B(tài)可以被修改廷支。
 * 如果存儲的是不可變對象频鉴,那么Triple 對象在創(chuàng)建后就保持不可變。
 *
 */
public abstract class Triple<L, M, R> implements Comparable<Triple<L, M, R>>, Serializable {

    /**
     * 一個(gè)空數(shù)組恋拍。
     */
    public static final Triple<?, ?, ?>[] EMPTY_ARRAY = new TripleAdapter[0];

    /**
     * 返回可分配而無需編譯器警告的空數(shù)組單例垛孔。
     *
     */
    @SuppressWarnings("unchecked")
    public static <L, M, R> Triple<L, M, R>[] emptyArray() {
        return (Triple<L, M, R>[]) EMPTY_ARRAY;
    }

    /**
     * 獲取由三個(gè)對象組成的不可變?nèi)M,推斷出泛型類型施敢。
     *
     * 此工廠方法允許使用推斷類型來創(chuàng)建三元組以獲取泛型類型周荐。
     *
     * @param left   左元素,可以為 null
     * @param middle 中間元素僵娃,可以為 null
     * @param right  右元素概作,可以為 null
     * @return 由三個(gè)參數(shù)形成的三元組,非 null
     */
    public static <L, M, R> Triple<L, M, R> of(final L left, final M middle, final R right) {
        return new ImmutableTriple<>(left, middle, right);
    }

    /**
     * 獲取此三元組的左元素默怨。
     *
     * @return 左元素讯榕,可以為 null
     */
    public abstract L getLeft();

    /**
     * 獲取此三元組的中間元素。
     *
     * @return 中間元素先壕,可以為 null
     */
    public abstract M getMiddle();

    /**
     * 獲取此三元組的右元素瘩扼。
     *
     * @return 右元素谆甜,可以為 null
     */
    public abstract R getRight();
}

Triple是一個(gè)抽象類垃僚,它有兩個(gè)子類:可變MutableTriple 以及不可變 ImmutableTriple

MutableTriple

MutableTriple 是可變的规辱,原因在于它提供了公共的設(shè)置(set)方法谆棺,允許在創(chuàng)建后修改其內(nèi)部值。具體來說,MutableTriple 提供了 setLeft改淑、setMiddlesetRight 方法碍岔,使得在對象創(chuàng)建后可以修改左、中朵夏、右元素的值蔼啦。

/**
 * 表示由三個(gè) {@code Object} 元素組成的可變?nèi)M。
 *
 * 非線程安全
 *
 */
public class MutableTriple<L, M, R> extends Triple<L, M, R> {


    /**
     * 通過推斷泛型類型獲取三個(gè)對象的可變?nèi)M仰猖。
     *
     * 該工廠允許通過推斷泛型類型創(chuàng)建三元組捏肢。
     *
     */
    public static <L, M, R> MutableTriple<L, M, R> of(final L left, final M middle, final R right) {
        return new MutableTriple<>(left, middle, right);
    }

    /** 左對象 */
    public L left;
    /** 中間對象 */
    public M middle;
    /** 右對象 */
    public R right;

    /**
     * 創(chuàng)建一個(gè)新的三元組實(shí)例,包含三個(gè) null 值饥侵。
     */
    public MutableTriple() {
    }

    /**
     * 創(chuàng)建一個(gè)新的三元組實(shí)例鸵赫。
     *
     * @param left   左值,可以為 null
     * @param middle 中間值躏升,可以為 null
     * @param right  右值辩棒,可以為 null
     */
    public MutableTriple(final L left, final M middle, final R right) {
        this.left = left;
        this.middle = middle;
        this.right = right;
    }

    /**
     * 設(shè)置三元組的左元素。
     */
    public void setLeft(final L left) {
        this.left = left;
    }

    /**
     * 設(shè)置三元組的中間元素膨疏。
     */
    public void setMiddle(final M middle) {
        this.middle = middle;
    }

    /**
     * 設(shè)置三元組的右元素一睁。
     */
    public void setRight(final R right) {
        this.right = right;
    }
}

MutableTriple 被明確標(biāo)記為非線程安全。

ImmutableTriple

ImmutableTriple 是一個(gè)不可變的三元組類成肘,由三個(gè)泛型元素(left卖局、middle、right)組成双霍。不可變意味著一旦創(chuàng)建砚偶,其狀態(tài)無法修改。該類被設(shè)計(jì)為線程安全的洒闸,但需要注意染坯,如果存儲在三元組中的對象是可變的,那么三元組本身實(shí)際上就不再是不可變的丘逸。

/**
 * 一個(gè)由三個(gè)元素組成的不可變?nèi)M单鹿。
 *
 * ImmutableTriple 是一個(gè)最終類,被設(shè)計(jì)成不可變的深纲,即在實(shí)例化后其狀態(tài)不可更改仲锄。
 * 如果存儲在三元組中的三個(gè)對象都是線程安全的,則該類是線程安全的湃鹊。類的最終性防止了子類化儒喊,確保不會添加不希望的行為。
 *
 * 線程安全的 如果三個(gè)對象都是線程安全的
 *
 */
public final class ImmutableTriple<L, M, R> extends Triple<L, M, R> {

    /**
     * 返回可以在不觸發(fā)編譯器警告的情況下分配的空數(shù)組單例币呵。
     * @return 可以在不觸發(fā)編譯器警告的情況下分配的空數(shù)組單例怀愧。
     */
    @SuppressWarnings("unchecked")
    public static <L, M, R> ImmutableTriple<L, M, R>[] emptyArray() {
        return (ImmutableTriple<L, M, R>[]) EMPTY_ARRAY;
    }

    /**
     * 返回一個(gè)由 null 組成的不可變?nèi)M。
     *
     * @return 一個(gè)由 null 組成的不可變?nèi)M。
     */
    public static <L, M, R> ImmutableTriple<L, M, R> nullTriple() {
        return NULL;
    }

    /**
     * 通過推斷泛型類型獲得由三個(gè)對象組成的不可變?nèi)M芯义。
     *
     * 此工廠允許使用推斷創(chuàng)建三元組以獲得泛型類型哈垢。
     *
     * @return 由三個(gè)參數(shù)形成的不可變?nèi)M,不為 null
     */
    public static <L, M, R> ImmutableTriple<L, M, R> of(final L left, final M middle, final R right) {
        return new ImmutableTriple<>(left, middle, right);
    }

    /** 左對象 */
    public final L left;
    /** 中間對象 */
    public final M middle;
    /** 右對象 */
    public final R right;

    /**
     * 構(gòu)造方法 創(chuàng)建一個(gè)新的三元組實(shí)例扛拨。
     *
     */
    public ImmutableTriple(final L left, final M middle, final R right) {
        this.left = left;
        this.middle = middle;
        this.right = right;
    }
}

ImmutableTriple 被聲明為 final耘分,表示不可繼承,確保不可變性绑警。確保不會有子類添加或修改行為陶贼。然后類中的屬性 leftmiddle待秃、right 被聲明為 final拜秧,表示它們在實(shí)例化后無法被修改。類中沒有提供修改元素的公共方法章郁。ImmutableTriple 主張不可變性枉氮,不提供修改實(shí)例狀態(tài)的方法。當(dāng)然如果存儲在三元組中的對象是可變的暖庄,則整個(gè)三元組就變得可變聊替。這是因?yàn)殡m然 ImmutableTriple 本身是不可變的,但如果存儲的對象是可變的培廓,它們的狀態(tài)可能會發(fā)生變化惹悄。

類聲明中使用 #ThreadSafe# 標(biāo)記,表示在存儲的三個(gè)對象都是線程安全的情況下肩钠,ImmutableTriple 是線程安全的泣港。

示例

/**  
* 返回可變Truple  
* @param userDO  
* @return  
*/  
private static MutableTriple<String, Integer, UserDO> handleUserInfo1(UserDO userDO){  
    return MutableTriple.of(userDO.getUserId(), userDO.getSex(), userDO);  
}  
  
/**  
* 返回不可變Triple  
* @param userDO  
* @return  
*/  
private static ImmutableTriple<String, Integer, UserDO> handleUserInfo2(UserDO userDO){  
    return ImmutableTriple.of(userDO.getUserId(), userDO.getSex(), userDO);  
}  
  
  
public static void main(String[] args) {  
    UserDO userDO = new UserDO();  
    userDO.setUserId("coderacademy");  
    userDO.setUserName("碼農(nóng)Academy");  
    userDO.setSex(1);  
      
    MutableTriple<String, Integer, UserDO> mutableTriple = handleUserInfo1(userDO);  
    System.out.println("mutableTriple改變前的值:" + mutableTriple);  
    mutableTriple.setMiddle(2);  
    System.out.println("mutableTriple改變后的值:" + mutableTriple);  
      
    ImmutableTriple<String, Integer, UserDO> immutableTriple = handleUserInfo2(userDO);  
    System.out.println("ImmutableTriple改變前的值:" + immutableTriple);  
    UserDO userFromTriple = immutableTriple.right;  
    userFromTriple.setSex(2);  
    System.out.println("ImmutableTriple改Right鍵值對象的值:" + immutableTriple);  
    // 因ImmutableTriple 不可變,無法通過set方法修改鍵值价匠。
}

總結(jié)

使用 Pair 和 Triple 類可以簡化代碼当纱、提高可讀性,使關(guān)聯(lián)數(shù)據(jù)更清晰踩窖,保持類型安全坡氯,增強(qiáng)代碼清晰度,提高擴(kuò)展性洋腮,并提供豐富的功能箫柳,從而使開發(fā)人員更高效地處理相關(guān)數(shù)據(jù),編寫更簡潔可讀的代碼啥供,提升代碼質(zhì)量和開發(fā)效率悯恍。

本文已收錄于我的個(gè)人博客:[碼農(nóng)Academy的博客,專注分享Java技術(shù)干貨滤灯,包括Java基礎(chǔ)坪稽、SpringBoot、SpringCloud鳞骤、Mysql窒百、Redis、Elasticsearch豫尽、中間件篙梢、架構(gòu)設(shè)計(jì)、面試題美旧、程序員攻略等渤滞。] (https://www.coderacademy.online/)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市榴嗅,隨后出現(xiàn)的幾起案子妄呕,更是在濱河造成了極大的恐慌,老刑警劉巖嗽测,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绪励,死亡現(xiàn)場離奇詭異,居然都是意外死亡唠粥,警方通過查閱死者的電腦和手機(jī)疏魏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晤愧,“玉大人大莫,你說我怎么就攤上這事」俜荩” “怎么了只厘?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舅巷。 經(jīng)常有香客問我懈凹,道長,這世上最難降的妖魔是什么悄谐? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任介评,我火速辦了婚禮,結(jié)果婚禮上爬舰,老公的妹妹穿的比我還像新娘们陆。我一直安慰自己,他們只是感情好情屹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布坪仇。 她就那樣靜靜地躺著,像睡著了一般垃你。 火紅的嫁衣襯著肌膚如雪椅文。 梳的紋絲不亂的頭發(fā)上喂很,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音皆刺,去河邊找鬼少辣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛羡蛾,可吹牛的內(nèi)容都是我干的漓帅。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼痴怨,長吁一口氣:“原來是場噩夢啊……” “哼忙干!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浪藻,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤捐迫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后爱葵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弓乙,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年钧惧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了暇韧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浓瞪,死狀恐怖懈玻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乾颁,我是刑警寧澤涂乌,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站英岭,受9級特大地震影響湾盒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诅妹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一罚勾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吭狡,春花似錦尖殃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弛秋,卻和暖如春器躏,著一層夾襖步出監(jiān)牢的瞬間俐载,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工登失, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遏佣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓壁畸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茅茂。 傳聞我的和親對象是個(gè)殘疾皇子捏萍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

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