怒肝一夜瑞筐,關(guān)于Java字符串的全部,都在這份手冊(cè)里了

String 可以說(shuō)是 Java 中最常見(jiàn)的數(shù)據(jù)類(lèi)型腊瑟,用來(lái)表示一串文本面哼,它的使用頻率非常高,為了小伙伴們著想扫步,我怒肝了一周魔策,把字符串能寫(xiě)的全都寫(xiě)了出來(lái)。

來(lái)看一下腦圖吧河胎,感受一下這份手冊(cè)涉及到的知識(shí)點(diǎn)闯袒,不是我吹,有了這份手冊(cè)游岳,字符串的相關(guān)知識(shí)可以說(shuō)全部掌握了政敢。

一、多行字符串

每個(gè)操作系統(tǒng)對(duì)換行符的定義都不盡相同胚迫,所以在拼接多行字符串之前喷户,需要先獲取到操作系統(tǒng)的換行符,Java 可以通過(guò)下面的方式獲确枚汀:

String newLine = System.getProperty("line.separator");

通過(guò) System 類(lèi)的 getProperty() 方法褪尝,帶上“l(fā)ine.separator”關(guān)鍵字就可以獲取到了闹获。

有了換行符,就可以使用 String 類(lèi)的 concat() 方法或者直接使用“+”號(hào)操作符拼接多行字符串了河哑。

String mutiLine = "親愛(ài)的"
        .concat(newLine)
        .concat("我想你了")
        .concat(newLine)
        .concat("你呢避诽?")
        .concat(newLine)
        .concat("有沒(méi)有在想我呢?");
String mutiLine1 = "親愛(ài)的"
        + newLine
        + "你好幼稚啊"
        + newLine
        + "技術(shù)文章里"
        + newLine
        + "你寫(xiě)這些合適嗎";

Java 8 的 String 類(lèi)加入了一個(gè)新的方法 join()璃谨,可以將換行符與字符串拼接起來(lái)沙庐,非常方便:

String mutiLine2 = String.join(newLine, "親愛(ài)的", "合適啊", "這叫趣味", "哈哈");

StringBuilder 當(dāng)然也是合適的:

String mutiLine3 = new StringBuilder()
        .append("親愛(ài)的")
        .append(newLine)
        .append("看不下去了")
        .append(newLine)
        .append("肉麻")
        .toString();

StringBuffer 類(lèi)似,就不再舉例了佳吞。

另外拱雏,Java 還可以通過(guò) Files.readAllBytes() 方法從源文件中直接讀取多行文本,格式和源文件保持一致:

String mutiLine4 = new String(Files.readAllBytes(Paths.get("src/main/resource/cmower.txt")));

二底扳、檢查字符串是否為空

說(shuō)到“空”這個(gè)概念古涧,它在編程中有兩種定義,英文單詞分別是 empty 和 blank花盐,來(lái)做一下區(qū)分羡滑。如果字符串為 null,或者長(zhǎng)度為 0算芯,則為 empty柒昏;如果字符串僅包含空格,則為 blank熙揍。

01职祷、empty

Java 1.6 之后,String 類(lèi)新添加了一個(gè) empty() 方法届囚,用于判斷字符串是否為 empty有梆。

boolean isEmpty(String str) {
    return str.isEmpty();
}

為了確保不拋出 NPE,最好在判斷之前先判空意系,因?yàn)?empty() 方法只判斷了字符串的長(zhǎng)度是否為 0:

所以我們來(lái)優(yōu)化一下 isEmpty() 方法:

boolean isEmpty(String str) {
    return str != null || str.isEmpty();
}

02泥耀、blank

如果想檢查字符串是否為 blank,有一種變通的做法蛔添,就是先通過(guò) String 類(lèi)的 trim() 方法去掉字符串兩側(cè)的空白字符痰催,然后再判斷是否為 empty:

boolean isBlank(String str) {
    return str != null || str.trim().isEmpty();
}

03、第三方類(lèi)庫(kù)

在實(shí)際的項(xiàng)目開(kāi)發(fā)當(dāng)中迎瞧,檢查字符串是否為空最常用的還是 Apache 的 commons-lang3 包夸溶,有各式各樣判空的方法。

更重要的是凶硅,可以省卻判 null 的操作缝裁,因?yàn)?StringUtils 的所有方法都是 null 安全的。

三足绅、生成隨機(jī)字符串

有時(shí)候捷绑,我們需要生成一些隨機(jī)的字符串韩脑,比如說(shuō)密碼。

int leftLimit = 97; // 'a'
int rightLimit = 122; // 'z'
int targetStringLength = 6;
Random random = new Random();
StringBuilder buffer = new StringBuilder(targetStringLength);
for (int i = 0; i < targetStringLength; i++) {
    int randomLimitedInt = leftLimit + (int)
            (random.nextFloat() * (rightLimit - leftLimit + 1));
    buffer.append((char) randomLimitedInt);
}
String generatedString = buffer.toString();

System.out.println(generatedString);

這段代碼就會(huì)生成一串 6 位的隨機(jī)字符串胎食,范圍是小寫(xiě)字母 a - z 之間扰才。

除了使用 JDK 原生的類(lèi)庫(kù)之外允懂,還可以使用 Apache 的 Commons Lang 包厕怜,RandomStringUtils.random() 方法剛好滿足需求:

int length = 6;
boolean useLetters = true;
// 不使用數(shù)字
boolean useNumbers = false;
String generatedString = RandomStringUtils.random(length, useLetters, useNumbers);

System.out.println(generatedString);

四、刪除字符串最后一個(gè)字符

刪除字符串最后一個(gè)字符蕾总,最簡(jiǎn)單的方法就是使用 substring() 方法進(jìn)行截取粥航,0 作為起始下標(biāo),length() - 1 作為結(jié)束下標(biāo)生百。

不管怎么樣递雀,substring() 方法不是 null 安全的,需要先判空:

    public static String removeLastChar(String s) {
        return (s == null || s.length() == 0)
                ? null
                : (s.substring(0, s.length() - 1));
    }

如果不想在操作之前判空蚀浆,那么就直接上 Apache 的 Commons Lang 包:

String s = "沉默王二";
StringUtils.substring(s, 0, s.length() - 1);

當(dāng)然了缀程,如果目的非常明確——就是只刪除字符串的最后一個(gè)字符,還可以使用 StringUtils 類(lèi)的 chop() 方法:

StringUtils.chop(s);

如果你看過(guò)源碼的話市俊,你就會(huì)發(fā)現(xiàn)杨凑,它內(nèi)部其實(shí)也是調(diào)用了 substring() 方法。

public static String chop(final String str) {
    if (str == null) {
        return null;
    }
    final int strLen = str.length();
    if (strLen < 2) {
        return EMPTY;
    }
    final int lastIdx = strLen - 1;
    final String ret = str.substring(0, lastIdx);
    final char last = str.charAt(lastIdx);
    if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
        return ret.substring(0, lastIdx - 1);
    }
    return ret;
}

如果你對(duì)正則表達(dá)式了解的話摆昧,也可以使用 replaceAll() 方法進(jìn)行替換现斋,把最后一個(gè)字符 .$ 替換成空字符串就可以了苗桂。

s.replaceAll(".$", "")

當(dāng)然了,replaceAll() 方法也不是 null 安全的,所以要提前判空:

String result= (s == null) ? null : s.replaceAll(".$", "");

如果對(duì) Java 8 的 Lambda 表達(dá)式和 Optional 比較熟的話能真,還可以這樣寫(xiě):

String result1 = Optional.ofNullable(s)
       .map(str -> str.replaceAll(".$", ""))
       .orElse(s);

看起來(lái)就顯得高大上多了,一看就是有經(jīng)驗(yàn)的 Java 程序員棠赛。

五漩氨、統(tǒng)計(jì)字符在字符串中出現(xiàn)的次數(shù)

要統(tǒng)計(jì)字符在字符串中出現(xiàn)的次數(shù),有很多方法偶垮,直接使用 JDK 的 API 就是最直接的一種:

String someString = "chenmowanger";
char someChar = 'e';
int count = 0;

for (int i = 0; i < someString.length(); i++) {
    if (someString.charAt(i) == someChar) {
        count++;
    }
}
System.out.println(count);

這種方式很直白礼殊,但有沒(méi)有更優(yōu)雅的呢?有针史,Java 8 就優(yōu)雅多了:

long count = someString.chars().filter(ch -> ch == 'e').count();

如果想使用第三方類(lèi)庫(kù)的話晶伦,可以繼續(xù)選擇 Apache 的 Commons Lang 包:

int count2 = StringUtils.countMatches("chenmowanger", "e");

也非常優(yōu)雅,很容易看得懂啄枕。

六婚陪、拆分字符串

大多數(shù)情況下,String 類(lèi)的 split() 方法就能夠滿足拆分字符串的需求:

String[] splitted = "沉默王二频祝,一枚有趣的程序員".split("泌参,");

當(dāng)然了脆淹,該方法也不是 null 安全的,那想要 null 安全沽一,小伙伴們應(yīng)該能想到誰(shuí)了吧盖溺?

之前反復(fù)提到的 StringUtils 類(lèi),來(lái)自 Apache 的 Commons Lang 包:

String[] splitted = StringUtils.split("沉默王二铣缠,一枚有趣的程序員", "烘嘱,");

如果對(duì)拆分字符串還有更多興趣的話,可以參考我之前寫(xiě)的另外一篇文章咦蝗蛙,拆分個(gè)字符串都這么講究蝇庭。

七、字符串比較

對(duì)于初學(xué)者來(lái)說(shuō)捡硅,最容易犯的錯(cuò)誤就是使用“==”操作符來(lái)判斷兩個(gè)字符串的值是否相等哮内,這也是一道很常見(jiàn)的面試題。

String string1 = "沉默王二";
String string2 = "沉默王二";
String string3 = new String("沉默王二");

System.out.println(string1 == string2);
System.out.println(string1 == string3);

這段程序的第一個(gè)結(jié)果是 true壮韭,第二個(gè)結(jié)果為 false北发,這是因?yàn)槭褂?new 關(guān)鍵字創(chuàng)建的對(duì)象和使用雙引號(hào)聲明的字符串不是同一個(gè)對(duì)象,而“==” 操作符是用來(lái)判斷對(duì)象是否相等的喷屋。

如果單純的比較兩個(gè)字符串的值是否相等琳拨,應(yīng)該使用 equals() 方法:

String string1 = "沉默王二";
String string2 = "沉默王二";
String string3 = new String("沉默王二");

System.out.println(string1.equals(string2));
System.out.println(string1.equals(string3));

這段程序輸出的結(jié)果就是兩個(gè) true,因?yàn)?equals() 方法就是用來(lái)單純的判斷字符串的值是否相等逼蒙。

關(guān)于 Java 字符串的比較从绘,可以參照我之前寫(xiě)的另外一篇文章如何比較 Java 的字符串

八是牢、字符串拼接

01僵井、“+”號(hào)操作符

要說(shuō)姿勢(shì),“+”號(hào)操作符必須是字符串拼接最常用的一種了驳棱,沒(méi)有之一批什。

String chenmo = "沉默";
String wanger = "王二";

System.out.println(chenmo + wanger);

我們把這段代碼使用 JAD 反編譯一下。

String chenmo = "\u6C89\u9ED8"; // 沉默
String wanger = "\u738B\u4E8C"; // 王二
System.out.println((new StringBuilder(String.valueOf(chenmo))).append(wanger).toString());

我去社搅,原來(lái)編譯的時(shí)候把“+”號(hào)操作符替換成了 StringBuilder 的 append 方法驻债。也就是說(shuō),“+”號(hào)操作符在拼接字符串的時(shí)候只是一種形式主義形葬,讓開(kāi)發(fā)者使用起來(lái)比較簡(jiǎn)便合呐,代碼看起來(lái)比較簡(jiǎn)潔,讀起來(lái)比較順暢笙以。算是 Java 的一種語(yǔ)法糖吧淌实。

02、StringBuilder

除去“+”號(hào)操作符,StringBuilder 的 append 方法就是第二個(gè)常用的字符串拼接姿勢(shì)了拆祈。

先來(lái)看一下 StringBuilder 類(lèi)的 append 方法的源碼:

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

這 3 行代碼沒(méi)啥可看的恨闪,可看的是父類(lèi) AbstractStringBuilder 的 append 方法:

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

1)判斷拼接的字符串是不是 null,如果是放坏,當(dāng)做字符串“null”來(lái)處理咙咽。appendNull 方法的源碼如下:

private AbstractStringBuilder appendNull() {
    int c = count;
    ensureCapacityInternal(c + 4);
    final char[] value = this.value;
    value[c++] = 'n';
    value[c++] = 'u';
    value[c++] = 'l';
    value[c++] = 'l';
    count = c;
    return this;
}

2)拼接后的字符數(shù)組長(zhǎng)度是否超過(guò)當(dāng)前值,如果超過(guò)淤年,進(jìn)行擴(kuò)容并復(fù)制钧敞。ensureCapacityInternal 方法的源碼如下:

private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
    }
}

3)將拼接的字符串 str 復(fù)制到目標(biāo)數(shù)組 value 中。

str.getChars(0, len, value, count)

03互亮、StringBuffer

先有 StringBuffer 后有 StringBuilder犁享,兩者就像是孿生雙胞胎余素,該有的都有豹休,只不過(guò)大哥 StringBuffer 因?yàn)槎嗪粑鼉煽谛迈r空氣,所以是線程安全的桨吊。

public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

StringBuffer 類(lèi)的 append 方法比 StringBuilder 多了一個(gè)關(guān)鍵字 synchronized威根,可暫時(shí)忽略 toStringCache = null

synchronized 是 Java 中的一個(gè)非常容易臉熟的關(guān)鍵字视乐,是一種同步鎖洛搀。它修飾的方法被稱為同步方法,是線程安全的佑淀。

04留美、String 類(lèi)的 concat 方法

單就姿勢(shì)上來(lái)看,String 類(lèi)的 concat 方法就好像 StringBuilder 類(lèi)的 append伸刃。

String chenmo = "沉默";
String wanger = "王二";

System.out.println(chenmo.concat(wanger));

文章寫(xiě)到這的時(shí)候谎砾,我突然產(chǎn)生了一個(gè)奇妙的想法。假如有這樣兩行代碼:

chenmo += wanger
chenmo = chenmo.concat(wanger)

它們之間究竟有多大的差別呢捧颅?

之前我們已經(jīng)了解到景图,chenmo += wanger 實(shí)際上相當(dāng)于 (new StringBuilder(String.valueOf(chenmo))).append(wanger).toString()

要探究“+”號(hào)操作符和 concat 之間的差別碉哑,實(shí)際上要看 append 方法和 concat 方法之間的差別挚币。

append 方法的源碼之前分析過(guò)了。我們就來(lái)看一下 concat 方法的源碼吧扣典。

public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    int len = value.length;
    char buf[] = Arrays.copyOf(value, len + otherLen);
    str.getChars(buf, len);
    return new String(buf, true);
}

1)如果拼接的字符串的長(zhǎng)度為 0妆毕,那么返回拼接前的字符串。

if (otherLen == 0) {
    return this;
}

2)將原字符串的字符數(shù)組 value 復(fù)制到變量 buf 數(shù)組中贮尖。

char buf[] = Arrays.copyOf(value, len + otherLen);

3)把拼接的字符串 str 復(fù)制到字符數(shù)組 buf 中笛粘,并返回新的字符串對(duì)象。

str.getChars(buf, len);
return new String(buf, true);

通過(guò)源碼分析我們大致可以得出以下結(jié)論:

1)如果拼接的字符串是 null,concat 時(shí)候就會(huì)拋出 NullPointerException闰蛔,“+”號(hào)操作符會(huì)當(dāng)做是“null”字符串來(lái)處理痕钢。

2)如果拼接的字符串是一個(gè)空字符串(""),那么 concat 的效率要更高一點(diǎn)序六。畢竟不需要 new StringBuilder 對(duì)象任连。

3)如果拼接的字符串非常多,concat 的效率就會(huì)下降例诀,因?yàn)閯?chuàng)建的字符串對(duì)象越多随抠,開(kāi)銷(xiāo)就越大。

注意了7蓖俊9八!

弱弱地問(wèn)一下啊扔罪,還有在用 JSP 的同學(xué)嗎秉沼?EL 表達(dá)式中是不允許使用“+”操作符來(lái)拼接字符串的,這時(shí)候就只能用 concat 了矿酵。

${chenmo.concat('-').concat(wanger)}

05唬复、String 類(lèi)的 join 方法

JDK 1.8 提供了一種新的字符串拼接姿勢(shì):String 類(lèi)增加了一個(gè)靜態(tài)方法 join。

String chenmo = "沉默";
String wanger = "王二";
String cmower = String.join("", chenmo, wanger);
System.out.println(cmower);

第一個(gè)參數(shù)為字符串連接符全肮,比如說(shuō):

String message = String.join("-", "王二", "太特么", "有趣了");

輸出結(jié)果為:王二-太特么-有趣了

我們來(lái)看一下 join 方法的源碼:

public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    // Number of elements not likely worth Arrays.stream overhead.
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

發(fā)現(xiàn)了一個(gè)新類(lèi) StringJoiner敞咧,類(lèi)名看起來(lái)很 6,讀起來(lái)也很順口辜腺。StringJoiner 是 java.util 包中的一個(gè)類(lèi)休建,用于構(gòu)造一個(gè)由分隔符重新連接的字符序列。限于篇幅评疗,本文就不再做過(guò)多介紹了测砂,感興趣的同學(xué)可以去了解一下。

06壤巷、StringUtils.join

實(shí)戰(zhàn)項(xiàng)目當(dāng)中邑彪,我們處理字符串的時(shí)候,經(jīng)常會(huì)用到這個(gè)類(lèi)——org.apache.commons.lang3.StringUtils胧华,該類(lèi)的 join 方法是字符串拼接的一種新姿勢(shì)寄症。

String chenmo = "沉默";
String wanger = "王二";

StringUtils.join(chenmo, wanger);

該方法更善于拼接數(shù)組中的字符串,并且不用擔(dān)心 NullPointerException矩动。

StringUtils.join(null)            = null
StringUtils.join([])              = ""
StringUtils.join([null])          = ""
StringUtils.join(["a", "b", "c"]) = "abc"
StringUtils.join([null, "", "a"]) = "a"

通過(guò)查看源碼我們可以發(fā)現(xiàn)有巧,其內(nèi)部使用的仍然是 StringBuilder。

public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
    if (array == null) {
        return null;
    }
    if (separator == null) {
        separator = EMPTY;
    }

    final StringBuilder buf = new StringBuilder(noOfItems * 16);

    for (int i = startIndex; i < endIndex; i++) {
        if (i > startIndex) {
            buf.append(separator);
        }
        if (array[i] != null) {
            buf.append(array[i]);
        }
    }
    return buf.toString();
}

大家讀到這悲没,不約而同會(huì)有這樣一種感覺(jué):我靠(音要拖長(zhǎng))篮迎,沒(méi)想到啊沒(méi)想到,字符串拼接足足有 6 種姿勢(shì)啊,晚上回到家一定要一一嘗試下甜橱。

07逊笆、為什么阿里開(kāi)發(fā)手冊(cè)不建議在 for 循環(huán)中使用”+”號(hào)操作符進(jìn)行字符串拼接

來(lái)看兩段代碼。

第一段岂傲,for 循環(huán)中使用”+”號(hào)操作符难裆。

String result = "";
for (int i = 0; i < 100000; i++) {
    result += "六六六";
}

第二段,for 循環(huán)中使用 append镊掖。

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    sb.append("六六六");
}

這兩段代碼分別會(huì)耗時(shí)多長(zhǎng)時(shí)間呢乃戈?在我的 iMac 上測(cè)試出的結(jié)果是:

1)第一段代碼執(zhí)行完的時(shí)間為 6212 毫秒

2)第二段代碼執(zhí)行完的時(shí)間為 1 毫秒

差距也太特么大了吧!為什么呢亩进?

我相信有不少同學(xué)已經(jīng)有了自己的答案:第一段的 for 循環(huán)中創(chuàng)建了大量的 StringBuilder 對(duì)象症虑,而第二段代碼至始至終只有一個(gè) StringBuilder 對(duì)象。

PS:第一版暫時(shí)先更新這么多归薛,后面遇到一些新的知識(shí)點(diǎn)的話谍憔,我再更新下一個(gè)版本。小伙伴們有建議的話苟翻,也可以提出來(lái)韵卤。

那可能有些小伙伴可能就忍不住了骗污,這份字符串手冊(cè)有沒(méi)有 PDF 版可以白嫖啊崇猫,那必須得有啊,直接微信搜「沉默王二」回復(fù)「字符串」就可以了需忿,不要手軟诅炉,覺(jué)得不錯(cuò)的,請(qǐng)多多分享——贈(zèng)人玫瑰屋厘,手有余香哦涕烧。

本文已收錄 GitHub,傳送門(mén)~ 汗洒,里面更有大廠面試完整考點(diǎn)议纯,歡迎 Star。

我是沉默王二溢谤,一枚有顏值卻靠才華茍且的程序員瞻凤。關(guān)注即可提升學(xué)習(xí)效率,別忘了三連啊世杀,點(diǎn)贊阀参、收藏、留言瞻坝,我不挑蛛壳,嘻嘻

?著作權(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)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斩祭,“玉大人劣像,你說(shuō)我怎么就攤上這事〈菝担” “怎么了耳奕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)诬像。 經(jīng)常有香客問(wèn)我屋群,道長(zhǎng),這世上最難降的妖魔是什么坏挠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任芍躏,我火速辦了婚禮,結(jié)果婚禮上降狠,老公的妹妹穿的比我還像新娘对竣。我一直安慰自己,他們只是感情好榜配,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布否纬。 她就那樣靜靜地躺著,像睡著了一般蛋褥。 火紅的嫁衣襯著肌膚如雪临燃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天烙心,我揣著相機(jī)與錄音膜廊,去河邊找鬼。 笑死弃理,一個(gè)胖子當(dāng)著我的面吹牛溃论,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痘昌,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼钥勋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼炬转!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起算灸,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扼劈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后菲驴,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一艺演、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婿失,春花似錦钞艇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挺物。三九已至懒浮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間识藤,已是汗流浹背砚著。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(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