《写给大忙人看的 Java 核心技术》 02 章练习

1.改变日历打印程序,让每周从周日开始。同时让它在结尾新打印一行(并且只新打印一行)。
01题参考答案:

package com.example;

import java.time.LocalDate;

public class LearnJava {

    public static void main(String[] args) throws Exception {

        System.out.println(" Mon Tue Wed Thu Fri Sat Sun");

        final int month = 11;
        LocalDate date = LocalDate.of(2017, month, 1);

        final int dayOfWeek = date.getDayOfWeek().getValue();

        for (int i=1; i<dayOfWeek; ++i) {
            System.out.printf("%4c", ' ');
        }

        while (date.getMonthValue() == month) {
            System.out.printf("%4d", date.getDayOfMonth());
            if (date.getDayOfWeek().getValue() == 7) {
                System.out.println();
            }
            date = date.plusDays(1);
        }

        final int continueValue = (8 - date.getDayOfWeek().getValue())%7 + 7;

        for (int i=0; i<continueValue; ++i) {
            System.out.printf("%4d", date.getDayOfMonth());
            if (date.getDayOfWeek().getValue() == 7) {
                System.out.println();
            }
            date = date.plusDays(1);
        }

    }
}

01题输出效果:

01题输出效果

2.思考一下 Scanner 类的 nextInt 方法。它是访问器方法还是修改器方法?为什么?那 Random 类的 nextInt 方法呢?

02题参考答案(个人理解):
Scanner 类的 nextInt 方法是修改器方法,因为它改变了 Scanner 类的状态,使其读取下一个输入。Random 类的 nextInt 方法是访问器方法,因为它只是用来返回随机整数,而不会改变 Random 类的状态。

3.你曾经写过返回值不为 void 的修改器方法吗?你曾有写过返回值为 void 的访问器方法吗?可能的话给个例子。
03题参考答案:

package com.example;

import java.util.ArrayList;

public class LearnJava {

    private static ArrayList<String> s_strings;

    // 静态初始化块
    static {
        s_strings = new ArrayList<>();
        s_strings.add("Mon");
        s_strings.add("Tue");
        s_strings.add("Wed");
        s_strings.add("Thu");
        s_strings.add("Fri");
    }

    // 返回值为 void 的访问器方法
    public void printWeekdays() {
        for (String string : s_strings) {
            System.out.printf("%4s", string);
        }
        System.out.println();
    }
    // 返回值不为 void 的修改器方法
    public boolean addSaturday() {
        if (s_strings.size() >= 5) {
            s_strings.add(5, "Sat");
            return true;
        }
        return false;
    }
    // 返回值不为 void 的修改器方法
    public boolean addSunday() {
        if (s_strings.size() >= 6) {
            s_strings.add(6, "Sun");
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws Exception {

        LearnJava learnJava = new LearnJava();
        learnJava.printWeekdays();
        learnJava.addSaturday();
        learnJava.printWeekdays();
        learnJava.addSunday();
        learnJava.printWeekdays();
    }
}

03题输出效果:

03题输出效果

4.为什么不能实现一个可以交换两个 int 变量内容的 Java 方法,但是却可以编写一个交换两个 IntHolder 对象内容的方法?(在 API 文档中查询这个比较晦涩的 IntHolder 类。)你能交换连个 Integer 对象的内容吗?

04题参考答案:
在 Java 中,所有参数 —— 对象引用以及基本类型值 —— 都是值传递。因此,不可能写出一个方法,将对象引用修改为其他东西。我们可以查看以下的实现,就能够理解为何要借助 IntHolder 类来实现两个 Integer 变量值的交换了:

package com.example;

import org.omg.CORBA.IntHolder;

public class LearnJava {

    private Integer s_integer_a = 1;
    private Integer s_integer_b = 2;

    public void printIntegerA_B() {
        System.out.println(s_integer_a + " " + s_integer_b);
    }

    public void swapIntegerA_B() {
        int temp = s_integer_a;
        s_integer_a = s_integer_b;
        s_integer_b = temp;
    }

    public void swapIntegerA_B(Integer a, Integer b) {
        int temp = a;
        a = b;
        b = temp;
    }

    public void swapIntegerA_B(IntHolder a, IntHolder b) {
        int temp = a.value;
        a.value = b.value;
        b.value = temp;
    }

    public static void main(String[] args) throws Exception {
        LearnJava learnJava = new LearnJava();
        learnJava.printIntegerA_B();
        learnJava.swapIntegerA_B();
        learnJava.printIntegerA_B();

        Integer a = 3;
        Integer b = 4;
        System.out.println(a + " " + b);
        learnJava.swapIntegerA_B(a, b);
        System.out.println(a + " " + b);

        IntHolder c = new IntHolder(5);
        IntHolder d = new IntHolder(6);
        System.out.println(c.value + " " + d.value);
        learnJava.swapIntegerA_B(c, d);
        System.out.println(c.value + " " + d.value);
    }
}

04题输出效果:

04题输出效果

5.实现一个描述平面上点的不可能修改的 Point 类。提供一个设置具体点的构造函数、一个设置为原点的无参数构造函数,以及方法 getX、getY、translate 和 scale。translate 方法根据给定量在 x 和 y 方向上移动该点。scale 方法根据给定因子在坐标系按比例变化。实现这些方法以便它们将新的 Point 对象作为结果返回。例如:

Point p = new Point(3, 4).translate(1, 3).scale(0.5);

应该设置 p 为坐标系上为(2, 3.5)的点。

05题参考答案:

package com.example;

public class LearnJava {

    public static class Point {
        private double x;
        private double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            this(0, 0);
        }

        public double getX() {
            return x;
        }

        public double getY() {
            return y;
        }

        public Point translate(double x, double y) {
            return new Point(this.x + x, this.y + y);
        }

        public Point scale(double s) {
            return new Point(this.x * s, this.y * s);
        }
    }

    public static void main(String[] args) {
        Point p = new Point(3, 4).translate(1, 3).scale(0.5);
        System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
    }
}

05题输出效果:

05题输出效果

6.重复前面的练习5,但是使得 translate 和 scale 方法变成修改器方法。

06题参考答案:

package com.example;

public class LearnJava {

    public static class Point {
        private double x;
        private double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Point() {
            this(0, 0);
        }

        public double getX() {
            return x;
        }

        public double getY() {
            return y;
        }

        public Point translate(double x, double y) {
            return new Point(this.x + x, this.y + y);
        }

        public Point scale(double s) {
            return new Point(this.x * s, this.y * s);
        }

        public void setTranslate(double x, double y) {
            this.x += x;
            this.y += y;
        }

        public void setScale(double s) {
            this.x *= s;
            this.y *= s;
        }
    }

    public static void main(String[] args) {
        Point p = new Point(3, 4).translate(1, 3).scale(0.5);
        System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
        p = new Point(3, 4);
        p.setTranslate(1, 3);
        p.setScale(0.5);
        System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
    }
}

06题输出效果:

06题输出效果

7.给前面两个版本的 Point 类添加 javadoc 注释。

07题参考答案:

package com.example;

public class LearnJava {

    /**
     * 一个 <code>Point</code> 对象代表一个坐标点
     * 坐标点中包含该坐标对应的横坐标的值 x 以及纵坐标的值 y
     * @author ZhaoDongshuang
     * @version 1.0
     */
    public static class Point {
        private double x;
        private double y;

        /**
         * 使用给定的 x 和 y 值构造一个坐标点对象
         * @param x 横坐标的值
         * @param y 纵坐标的值
         */
        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        /**
         * 使用原点坐标构造一个坐标点对象
         */
        public Point() {
            this(0, 0);
        }

        /**
         * 获取横坐标的值
         * @return 返回 double 类型的横坐标的值
         */
        public double getX() {
            return x;
        }

        /**
         * 获取纵坐标的值
         * @return 返回 double 类型的纵坐标的值
         */
        public double getY() {
            return y;
        }

        /**
         * 获取相对原坐标点移动之后的坐标点,该方法不改变原有坐标点的状态
         * @param x 横坐标的移动量
         * @param y 纵坐标的移动量
         * @return 返回移动之后的坐标点
         */
        public Point translate(double x, double y) {
            return new Point(this.x + x, this.y + y);
        }

        /**
         * 获取相对原坐标点缩放之后的坐标点,该方法不改变原有坐标点的状态
         * @param s 缩放因子
         * @return 返回缩放之后的坐标点
         */
        public Point scale(double s) {
            return new Point(this.x * s, this.y * s);
        }

        /**
         * 将坐标点按照给定的横纵坐标值进行移动
         * @param x 横坐标的移动量
         * @param y 纵坐标的移动量
         */
        public void setTranslate(double x, double y) {
            this.x += x;
            this.y += y;
        }

        /**
         * 将坐标点按照给定的缩放因子值进行缩放
         * @param s 缩放因子
         */
        public void setScale(double s) {
            this.x *= s;
            this.y *= s;
        }
    }

    public static void main(String[] args) {
        Point p = new Point(3, 4).translate(1, 3).scale(0.5);
        System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
        p = new Point(3, 4);
        p.setTranslate(1, 3);
        p.setScale(0.5);
        System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
    }
}

8.在前面的练习中,提供的 Point 类的这些构造函数和 getter 方法有些重复。大多数 IDE 为编写样板代码都提供了快捷方式。你的 IDE 都提供了哪些?

Android Studio 中在光标选中构造函数,键盘快捷键 “alt+insert”,显示构造函数的快速构建方法如下:

Android Studio 构造函数 快速构建方法

Android Studio 中在光标选中某个变量,键盘快捷键 “alt+insert”,显示变量的快速构建方法如下:

Android Studio 类的变量 快速构建方法

9.实现一个 Car 类,模拟汽车沿着 x 轴移动,随着移动消耗燃油。提供一个按照给定英里数驱动汽车的方法、给汽车燃料箱添加给定加仑(燃油)的方法,以及获取原点到油位的当前距离的方法。在构造函数中指定燃料效率(单位为每加仑多少英里)。Car 类应该是不可修改类吗?为什么或者为什么不应该?

09题参考答案:

package com.example;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class LearnJava {

    public static class Car {
        private BigDecimal burningPower;
        private BigDecimal oilVolume;
        private BigDecimal miles;

        public Car(BigDecimal burningPower, BigDecimal oilVolume, BigDecimal miles) {
            this.burningPower = burningPower;
            this.oilVolume = oilVolume;
            this.miles = miles;
        }

        public Car(BigDecimal burningPower, BigDecimal oilVolume) {
            this(burningPower, oilVolume, new BigDecimal(0));
        }

        public Car(BigDecimal burningPower) {
            this(burningPower, new BigDecimal(0), new BigDecimal(0));
        }

        public void move(BigDecimal miles) {
            if (oilVolume.compareTo(miles.divide(burningPower,
                    RoundingMode.UP)) == 1) {
                this.miles = this.miles.add(miles);
            } else {
                this.miles = this.miles.add(oilVolume.multiply(burningPower));
            }
        }

        public void addOil(BigDecimal oilVolume) {
            this.oilVolume = this.oilVolume.add(oilVolume);
        }

        public BigDecimal getMiles() {
            return miles;
        }
    }

    public static void main(String[] args) {
        // 使用下面第一种方式的 2.3 初始化 BigDecimal,其值将变成 2.2999999999999998,
        // 所以建议使用第二种方式赋值
        // method 1
//        Car car = new Car(new BigDecimal(2.3), new BigDecimal(100));
        // method 2
        Car car = new Car(new BigDecimal("2.3"), new BigDecimal(100));
        car.move(new BigDecimal(200));

        System.out.println("Current move miles: " + car.getMiles().toString());
    }
}

09题输出效果:

09题输出效果

虽然我们想要这台车开个 400 英里,但是在当前的燃烧率和油量下,最多只能开到 230 英里。

10.在 RandomNumbers 类中,提供两个静态方法 randomElement,从数组或者整数数组列表中获得随机元素。(如果数组或者数组列表为空,则返回 0。)为什么不能使这两个方法成为 int [] 或 ArrayList<Integer> 的实例方法?

10题参考答案:

package com.example;

import java.util.ArrayList;
import java.util.Random;

public class LearnJava {

    static class RandomNumbers {

        private static Random s_random;

        static {
            s_random = new Random();
            s_random.setSeed(System.currentTimeMillis());
        }

        public static Object randomElement(ArrayList<?> arrayList) {
            if (arrayList.size() == 0) {
                return 0;
            }
            return arrayList.get(Math.abs(s_random.nextInt())%(arrayList.size() - 1));
        }

//        public static Object randomElement(Integer[] arrayList) {
//            return randomElement(new ArrayList<>(Arrays.asList(arrayList)));
//        }

        public static Object randomElement(int[] arrayList) {
            ArrayList<Integer> intList = new ArrayList<>();
            for (Integer i : arrayList) {
                intList.add(i);
            }
            return randomElement(intList);
        }

    }

    public static void main(String[] args) {

        ArrayList<Integer> integers = new ArrayList<>();
        for (int i=0; i<100; ++i) {
            integers.add(i);
        }
        System.out.println(RandomNumbers.randomElement(integers).toString());

        int[] arrays = new int[100];
        for (int i=0; i<100; ++i) {
            arrays[i] = i;
        }
        System.out.println(RandomNumbers.randomElement(arrays).toString());
    }

}

10题输出效果:

10题输出效果

为什么不能使这两个方法成为 int [] 或 ArrayList<Integer> 的实例方法?
这是因为在 Java 中,基本类型不是类。无法创建其对象,即无法实现通过对象对方法的调用。

11.对 System 和 LocalDate 类使用静态导入,重写 Cal 类。

11题参考答案:

package com.example;

import java.time.LocalDate;
import static java.time.LocalDate.of;

public class LearnJava {

    public static void main(String[] args) throws Exception {

        System.out.println(" Mon Tue Wed Thu Fri Sat Sun");

        final int month = 11;
        LocalDate date = of(2017, month, 1);

        final int dayOfWeek = date.getDayOfWeek().getValue();

        for (int i=1; i<dayOfWeek; ++i) {
            System.out.printf("%4c", ' ');
        }

        while (date.getMonthValue() == month) {
            System.out.printf("%4d", date.getDayOfMonth());
            if (date.getDayOfWeek().getValue() == 7) {
                System.out.println();
            }
            date = date.plusDays(1);
        }

        final int continueValue = (8 - date.getDayOfWeek().getValue())%7 + 7;

        for (int i=0; i<continueValue; ++i) {
            System.out.printf("%4d", date.getDayOfMonth());
            if (date.getDayOfWeek().getValue() == 7) {
                System.out.println();
            }
            date = date.plusDays(1);
        }

    }
}

11题输出效果:

11题输出效果

11题的示例中,我只是使用了 of 这个静态方法,因此,就仅仅改动了两行代码

import static java.time.LocalDate.of;
//...
LocalDate date = of(2017, month, 1);

12.创建一个 HelloWorld.java 文件,它在包 ch01.sec01 中声明了 HelloWorld 类。把它放在某个目录,但不在 ch01/sec01 子目录。从存放文件的那个目录运行 javac HelloWorld.java。你会得到类文件吗?类文件存放在哪里?接着运行 java HelloWorld 会发生什么?为什么?(提示:运行 javap HelloWorld 并研究告警信息。)最后,为什么 javac -d . HelloWorld.java 更好?

12题参考答案:
会得到类文件,文件存放在 HelloWorld.java 所在的目录

运行

java HelloWorld

会提示错误:

错误: 找不到或无法加载主类 HelloWorld

通过运行

javap HelloWorld

我们可以知道这是因为:

警告: 二进制文件HelloWorld包含ch01.sec01.LearnJava

也就是无法正确的找到相应的文件。

而使用

javac -d . HelloWorld.java

的好处是,class 文件会产生在单独的目录中,不会搞乱代码树,并且 class 文件也有正确的子目录结构。

运行完

javac -d . HelloWorld.java

再执行

java ch01.sec01.LearnJava

就可以得到正常的输出了。

13.从 http://opencsv.sourceforge.net 下载 OpenCSV 的 JAR 文件。写个有 main 方法的类,读取你选择的 CSV 文件并打印部分内容。OpenCSV 网站上有示例代码。我们还未学习处理异常。先用下面的内容作为 main 方法头:

public static void main(String[] args) throws Exception

这个练习的目的不是让我们用 CSV 文件做些有用的事情,而是练习如何使用交付为 JAR 文件格式的类库。

13题参考答案:

在 Android Studio 中,我们将下载的 jar 包,放到 libs 目录中:

放到 libs 目录中
放到 libs 目录之后

在 Android Studio 中,选择需要加入 JAR 包的 java module,点击鼠标右键:

点击鼠标右键

选择 “Open Module Settings” 选项:

选择 “Open Module Settings” 选项

点击新弹出的窗口的右侧的 “+” 符号,选择 “jar dependency” 选项:


选择 “jar dependency”

在弹出的窗口中选择我们刚刚放到 libs 中的 JAR 包:

选择 JAR 包

下面是测试代码(其实不好用),只是我们可以引用 JAR 包中的方法了。

package com.example;

import com.opencsv.CSVReader;

import java.io.FileReader;
import java.util.List;

public class LearnJava {

    public static void main(String[] args) throws Exception {
        CSVReader reader = new CSVReader(
                new FileReader("/home/toby/SampleCSVFile_10600kb.csv"));

        List<String[]> myEntries = reader.readAll();
    }
}

14.编译 Network 类。注意内部类文件被命名为 Network$Member.class。使用 javap 程序检查生成的代码。命令

javap -private Classname

显示方法和实例变量。你在哪里看到外部类的引用?(在 Linux/Mac OS X 系统上,运行 javap 时,在 $ 符号前你需要输入 “\”。)

14题参考答案:
我没有编译 Network 类,而是将第10题的例子编译了一下:

package com.example;

import java.util.ArrayList;
import java.util.Random;

public class LearnJava {

    static class RandomNumbers {

        private static Random s_random;

        static {
            s_random = new Random();
            s_random.setSeed(System.currentTimeMillis());
        }

        public static Object randomElement(ArrayList<?> arrayList) {
            if (arrayList.size() == 0) {
                return 0;
            }
            return arrayList.get(Math.abs(s_random.nextInt())%(arrayList.size() - 1));
        }

//        public static Object randomElement(Integer[] arrayList) {
//            return randomElement(new ArrayList<>(Arrays.asList(arrayList)));
//        }

        public static Object randomElement(int[] arrayList) {
            ArrayList<Integer> intList = new ArrayList<>();
            for (Integer i : arrayList) {
                intList.add(i);
            }
            return randomElement(intList);
        }

    }

    public static void main(String[] args) {

        ArrayList<Integer> integers = new ArrayList<>();
        for (int i=0; i<100; ++i) {
            integers.add(i);
        }
        System.out.println(RandomNumbers.randomElement(integers).toString());

        int[] arrays = new int[100];
        for (int i=0; i<100; ++i) {
            arrays[i] = i;
        }
        System.out.println(RandomNumbers.randomElement(arrays).toString());
    }

}

对上述代码所在的类文件 LearnJava.java 运行:

javac -d . LearnJava.java

之后14题测试的效果如下:

14题测试的效果

15.完整实现 2.6.1 节中的 Invoice 类。提供一个打印 invoice 的方法,以及构造并打印示例 invoice 的演示程序。

15题参考答案:

package com.example;

import java.util.ArrayList;

public class LearnJava {

    static class Invoice {
        public static class Item {
            String description;
            int quantity;
            double unitPrice;

            public Item() {
                this("", 0, 0);
            }

            public Item(String description, int quantity, double unitPrice) {
                this.description = description;
                this.quantity = quantity;
                this.unitPrice = unitPrice;
            }


            double price() {
                return quantity * unitPrice;
            }
        }

        private ArrayList<Item> items = new ArrayList<>();

        public void addItem(String description, int quantity, double unitPrice) {
            Item newItem = new Item();
            newItem.description = description;
            newItem.quantity = quantity;
            newItem.unitPrice = unitPrice;
            items.add(newItem);
        }

        public void addItem(Item item) {
            items.add(item);
        }

        public void printInvoice() {
            for (Item item : items) {
                System.out.print("description: " + item.description + ", ");
                System.out.print("quantity: " + item.quantity + ", ");
                System.out.println("unitPrice: " + item.unitPrice);
            }
        }
    }

    public static void main(String[] args) {
        Invoice invoice = new Invoice();
        invoice.addItem("Tomato", 12, 5);
        Invoice.Item item0 = new Invoice.Item("Potato", 11, 6);
        invoice.addItem(item0);

        invoice.printInvoice();
    }

}

15题输出效果:

15题输出效果

16.实现一个 Queue 类 —— 一个无边界的字符串队列,分别提供在末尾添加字符串的 add 方法和从队列头部进行删除的 remove 方法。将元素存储成链表节点。创建一个嵌套类 Node。Node 类应该是静态类或不应该是静态类吗?

16题参考答案:
静态嵌套类没有外部类的引用。当嵌套类的实例不需要知道它属于外部类的哪个实例时,使用静态嵌套类。只有当这种信息重要时,才使用内部类。

对于这个队列来说因为 Node 无需访问 Queue 的成员或者方法,所以,Node 可以是静态的嵌套类。

package com.example;

import java.util.ArrayList;

public class LearnJava {

    static class Queue {

        private ArrayList<Node> nodes = new ArrayList<>();

        public static class Node {
            public String getContent() {
                return content;
            }

            private String content;

            public Node() {
                this.content = "";
            }

            public Node(String content) {
                this.content = content;
            }
        }

        public int size() {
            return nodes.size();
        }

        public void add(String value) {
            Node node = new Node(value);
            nodes.add(node);
        }

        public void remove() {
            if (nodes.size() > 0) {
                nodes.remove(0);
            }
        }

        public void printValue(int i) {
            if (i>=0 && i < nodes.size()) {
                System.out.println(nodes.get(i).getContent());
            } else {
                System.out.println();
            }
        }
    }

    public static void main(String[] args) {

        Queue queue = new Queue();

        for (int i=0; i<50; ++i) {
            queue.add(String.valueOf(i));
        }

        int i = 40;
        while (i>0) {
            queue.remove();
            --i;
        }

        for (i=0; i<queue.size(); ++i) {
            queue.printValue(i);
        }
    }

}

16题输出效果:

16题输出效果

17.提供一个 iterator —— 依次产生队列元素的对象 —— 就是上一道练习题中的队列。将 Interator 作为拥有 next 和 hasNext 方法的嵌套类。给 Queue 类提供 iterator() 方法,该方法产生 Queue.Iterator。Iterator 应该是静态类或不应该是静态类吗?

17题参考答案:

Iterator 不应该是静态嵌套类,因为它需要访问外部类的非静态成员。

package com.example;

import java.util.ArrayList;

public class LearnJava {

    static class Queue {

        private ArrayList<Node> nodes = new ArrayList<>();

        public static class Node {
            public String getContent() {
                return content;
            }

            private String content;

            public Node() {
                this.content = "";
            }

            public Node(String content) {
                this.content = content;
            }
        }

        public class Iterator {

            private int i = -1;

            public Iterator() {
                i = -1;
            }

            public Iterator(int i) {
                this.i = i;
            }

            public Node next() {
                return nodes.get(++i);
            }

            public boolean hasNext() {
                return (i+1) < nodes.size();
            }
        }

        public int size() {
            return nodes.size();
        }

        public void add(String value) {
            Node node = new Node(value);
            nodes.add(node);
        }

        public void remove() {
            if (nodes.size() > 0) {
                nodes.remove(0);
            }
        }

        public void printValue(int i) {
            if (i>=0 && i < nodes.size()) {
                System.out.println(nodes.get(i).getContent());
            } else {
                System.out.println();
            }
        }

        public Iterator iterator() {
            return new Iterator(-1);
        }
    }

    public static void main(String[] args) {

        Queue queue = new Queue();

        for (int i=0; i<50; ++i) {
            queue.add(String.valueOf(i));
        }

        int i = 40;
        while (i>0) {
            queue.remove();
            --i;
        }

        Queue.Iterator iterator = queue.iterator();
        while (iterator.hasNext()) {
            Queue.Node node = iterator.next();
            System.out.println(node.getContent());
        }
    }

}

17题输出效果:

17题输出效果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339