• java学习--day24(单例模式&序列化&Lambda表达式)


    回顾

    1.三种创建Class对象的形式
    	Class.forName("")
    	类.class
    	对象.getCalss()
    	字节文件.class对象
    2.Class下面获取构造方法对象的方法
    	getConstructors();
    	getDeclaredConstructors();
    	getConstructor(Class  ..... parameterType);
    	getDeclaredConstructor(Class  ..... parameterType);
    3.Class下面获取方法对象的方法
    	getMethods();
    	getDeclaredMethods();
    	getMethod(String name, Class .... parameterType);
    	getDeclaredMethod(String name, Class .... parameterType);
    4.Class下面获取属性对象的方法
    	getFields();
    	getDeclaredFields();
    	getField(String name);
    	getDeclaredField(String name);
    5.Constructor对象下面的方法
    	newInstance(); 通过构造方法创建了实例对象
    	setAccessible(true);
    6.Method对象下面的方法
    	setAccessible(true);
    	invoke(Object  obj, Object ... param);
    7.Field对象下面的方法
    	setAccessible(true);
    	set(Object obj, Object value);
    8.简单聊聊对反射的理解
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    今天的内容

    1.单例模式

    2.序列化操作(IO流)

    以下两个是jdk的新特性:

    3.lambda表达式

    4.Stream流

    1.单例模式

    Java提供了二十多种设计模式,在咱们教学过程中抽重要的学习,开发中用的

    模式并不是一朝一夕学会的东西,工厂模式, 代理模式 策略模式等

    设计模式是全球公认的。为了让咱们的代码变得更加简洁,效率更高,产生出来的模式

    修改的时候更加方便

    单例模式:

    ​ 要求在整个程序运行过程中,只出现一个实例对象。减少内存的消耗

    ​ 如何判断两个对象或者多个对象是否是单例,看内存地址。如果内存地址相等的话,绝对是同一个对象。

    想一些问题:

    ​ 创建对象 通过关键字 new 来创建,但是new一次 再new一次对象的内存地址绝对不一样的。就意味着你必须将一个类的构造方法私有化

    package com.qfedu.f_singleinstance;
    
    class SingDog {
        private static  SingDog singDog = null;
        private SingDog () {
    
        }
        public  static SingDog getInstance() {
    
            synchronized (SingDog.class) {
                if (singDog == null) {
                    //
                    singDog = new SingDog();
                }
            }
            return singDog;
        }
    
    
    }
    class MyThread1 implements Runnable {
        @Override
        public void run() {
            SingDog instance = SingDog.getInstance();
            System.out.println(instance);
        }
    }
    class MyThread2 implements Runnable {
        @Override
        public void run() {
            SingDog instance = SingDog.getInstance();
            System.out.println(instance);
        }
    }
    
    public class Demo1 {
        public static void main(String[] args) {
    
            //以上两个对象是两个不同的对象。单例模式的目的
            //是只能有一个对象,不能有多个对象,就意味着不能再new
            //为啥?new一个就是对象。不能new 在类里面咋写?
            //解决方案: 私有话构造方法
            //不能new  想得到对象? 在类中定义一个静态方法
            //为啥是静态方法  只能用来调用
    //        SingDog singdog = SingDog.getInstance();
    //
    //        System.out.println(singdog);
    //        SingDog singdog1 = SingDog.getInstance();
    //        System.out.println(singdog1);
            new Thread(new MyThread1()).start();
            new Thread(new MyThread2()).start();
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    懒汉式的写法

    package com.qfedu.a_single;
    
    //懒汉式写法
    class Person {
        private static Person person;
        private Person () {
    
        }
        public static synchronized Person getInstance ()  {
            if  (person == null) {
                person = new Person();
            }
            return person;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    饿汉式写法

    package com.qfedu.a_single;
    
    class Cat {
        private static final Cat cat = new Cat();
        private Cat() {
    
        }
        public static Cat getIntance () {
            return cat;
        }
    }
    public class Demo3 {
        public static void main(String[] args) {
            Cat intance = Cat.getIntance();
            Cat intance1 = Cat.getIntance();
            System.out.println(intance);
            System.out.println(intance1);
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    懒汉式:线程不安全

    饿汉式:线程安全的

    效率来说: 饿汉式效率高,因为不用加锁

    性能来说: 饿汉式类一加载就实力出来对象。但是懒汉式调用方法的时候才进行创建对象

    懒汉式的内存消耗是小于饿汉式的

    2.序列化

    和IO流有关

    类 ObjectInputStream(反序列化) 和 ObjectOutputStream(序列化) 是高层次的数据流,它们包含反序列化和序列化对象的方法。

    ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:

    public final void writeObject(Object x) throws IOException

    上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:

    public final Object readObject() throws IOException, ClassNotFoundException

    该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。

    总结:序列化能干嘛? 将一个类对象信息(构造方法,属性,方法)可以写到本地一个文件中。这叫序列化。从文件中读取一个对象的信息,这叫反序列化。

    序列化注意事项:

    ​ 1.被序列化的实体类必须实现一个接口 Serializable,不然不能被序列化

    序列化案例:

    将一个对象赋值完以后写到到本地。ObjectOutputStream

    package com.qfedu.b_serialize;
    
    import java.io.*;
    import java.util.ArrayList;
    
    public class Demo1 {
        public static void main(String[] args) throws Exception {
            //序列化:将对象存到一个文件中
            Employee employee = new Employee();
            employee.name = "马斯克";
            employee.address = "月球";
            employee.number = 100;
            employee.mailCheck();
            //将employee对象进行序列化 存到一个文件中  序列化的文件的后缀都是.ser
            FileOutputStream fos = new FileOutputStream(new File("c:/aaa/emp.ser"));
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fos);
            objectOutputStream.writeObject(employee);
            objectOutputStream.close();
            fos.close();
            System.out.println("写入成功");
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    反序列化

    将本地的文件信息(被序列化过的)写到一个对象中

    ObjectInputStream

    package com.qfedu.b_serialize;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    public class Demo2 {
        public static void main(String[] args) throws Exception{
            //进行反序列化
            FileInputStream fis = new FileInputStream(new File("c:/aaa/emp1.ser"));
            ObjectInputStream ois = new ObjectInputStream(fis);
            Employee emp = (Employee)ois.readObject();
            System.out.println(emp.name);
            System.out.println(emp.number);
            System.out.println(emp.address);
            System.out.println(emp.sb);
            emp.mailCheck();
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    总结:序列化将对象的值存到本地磁盘的文件中以作备份。反序列化可以将本次磁盘序列化过的文件读取到实体类的对象中。

    3.Lambda表达式

    Lambda表达式被称称为闭包。他是推动了Java8新特性的重要的一步。

    Lambda表达式运行函数式编程。就是简化代码的。变得更加简洁,但是可读性特别差

    3.1入门案例
    package com.qfedu.c_lambda;
    
    public class Demo1 {
        public static void main(String[] args) {
            //新建一个线程
            //第一种的创建方式
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("简洁嘻嘻哒" + i);
                    }
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("锤人" + i);
                    }
                }
            }).start();
    
            //Thread构造方法是接口对象
            Runnable runnable = ()-> System.out.println("嘻嘻");
            new Thread(runnable).start();
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    3.2lambda表达式语法格式

    只看接口下面的唯一的一个抽象方法。

    接口  接口对象 =  ()->表达式;  无参 无返回值的
    接口  接口对象 =  (parameter)->表达式;  有参  无返回值的
    接口  接口对象 = ()->{表达式;};   无参 有返回值的
    接口  接口对象 = (parameter)->{表达式;};  有参有返回值
    
    • 1
    • 2
    • 3
    • 4
    3.2.1无参无返回值的形式
    package com.qfedu.c_lambda;
    
    interface Computer {
        void coding();
    }
    public class Demo4 {
        public static void main(String[] args) {
            //无参无返回值的
            test(() -> System.out.println("敲代码"));
        }
        //而如果一个方法的参数是一个接口对象的话,难免要new 这个接口 重写方法
        
        public static void test (Computer c) {
            c.coding();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    3.2.2有参无返返回值的方法
    package com.qfedu.c_lambda;
    
    interface C {
        void eat(String name, int a);
    }
    public class Demo5 {
        public static void main(String[] args) {
            test(( name,  a) -> System.out.println(name + "吃" + a) , "狗蛋", 4);
        }
        public static void test (C c, String name, int a) {
            c.eat(name , a);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    3.2.3无参有返回值
    package com.qfedu.c_lambda;
    
    interface D {
        int num();
    }
    public class Demo6 {
        public static void main(String[] args) {
            test(() ->{
                    if (true) {
                        System.out.println("xixida");
                    }
                    return 500;
                });
        }
        public static void test (D d) {
            d.num();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    3.2.4有参有返回值的
    package com.qfedu.c_lambda;
    
    interface E {
        int add(int a, int b);
    }
    public class Demo7 {
        public static void main(String[] args) {
            test((a, b) -> a + b, 2, 3);
    
        }
        public static void test (E e, int a, int b) {
            int sum = e.add(a, b);
            System.out.println(sum);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    算法工程师 | 如何快速 了解,掌握一个算法!脚踏实地,迎着星辰,向前出发 ~
    centos jdk 安装
    laravel 事件 & 监听
    软件设计思想
    便捷高效的电能管理:利用PLC远程控制网关实时监控配电箱
    【计算机网络实验】TCP和UDP传输过程仿真与分析
    【微信小程序毕业设计源代码】最近开发的60个java+python微信小程序源码+毕业设计选题推荐
    数据结构--》解锁数据结构中树与二叉树的奥秘(二)
    Spring中毒太深,离开Spring我连最基本的CRUD都不会写了...
    【Call for papers】DSN-2023(CCF-B/截稿日期: 2022年12月7日)
  • 原文地址:https://blog.csdn.net/m0_46202060/article/details/133757691