Java设计(单例)模式+初涉线程+计算每个单词出现的次数+归并和效率

Java日报

部门: **大数据开发六部

姓名: cqmfx(阡陌飞絮)

日期: 2020.11.7

大纲

一、设计(单例)模式

二、初涉线程

三、初涉异常

四、计算每个单词出现的次数

五、归并和效率

Java单例模式+初涉线程+计算每个单词出现的次数+归并和效率

一、设计(单例)模式

1、设计模式的类别(经常使用)

工厂模式(常用)

抽象工厂模式

单例模式(常用)

桥接模式

装饰器模式

代理模式(常用)

观察者模式

策略模式

模板模式

2、单例模式

1)定义

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。
2)介绍

**意图:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。

**主要解决:**一个全局使用的类频繁地创建与销毁。

**何时使用:**当您想控制实例数目,节省系统资源的时候。

**如何解决:**判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

**关键代码:**构造函数是私有的。

3)懒汉模式
package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class SingLeton2 {
    /**
     * 懒汉式
     */
    // 不去内存里分配空间    
    // 需要一个静态的成员变量保存咱们的实例
    private static SingLeton2 SINGTION2;
    // 私有化的构造器 不让外面new   
    // 不能通过new关键字来构造对象
    private SingLeton2(){}
    // 持有一个方法,这个方法能返回内存当中的实例    
    // 通过getInstance来获取 调取这个方法 看一下静态的变量 如果是空 new一个    
    // 不是空就进不了方法 直接返回  用的时候new  不用的时候 就不new  不到最后的时候不干 
    public static SingLeton2 getInstance() {
        if (SINGTION2 == null){
            SINGTION2 = new SingLeton2();
        }
        return  SINGTION2;		//不合格写法
    }
}
4)饿汉模式
package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class SingLeton {
    /**
     * 饿汉式,无线程安全,占空间,在内存里只能有一个对象存在,且不能通过new引用
     */
    private final static SingLeton SINGLENT = new SingLeton();
    private SingLeton(){}
    // 如果需要 用getInstance 就能得到想要的类或对象 内存里只有一份
    public static SingLeton getInstance() {
        return SINGLENT;
    }
}

二、初涉线程

1、简介

线程是程序中执行的线程。Java虚拟机允许应用程序同时执行多个执行线程。

每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。

Thread属于Lang包

Java.lang.Object 
java.lang.Thread

当Java虚拟机启动时,通常有一个非守护进程线程(通常调用某些指定类的名为main的方法)。 Java虚拟机将继续执行线程,直到发生以下任一情况:

  • 已经调用了Runtime类的exit方法,并且安全管理器已经允许进行退出操作。
  • 所有不是守护进程线程的线程都已经死亡,无论是从调用返回到run方法还是抛出超出run方法的run

创建一个新的执行线程有两种方法。 一个是将一个类声明为Thread的子类。 这个子类应该重写run类的方法Thread , 然后可以分配并启动子类的实例

同步方法: 使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着

2、StringBuilder和StringBuffer

  • StringBuffer中的方法都使用了synchronized修饰符,表示同步的,在多线程并发的时候可以保证线程安全,保证线程安全的时候,性能(速度)较低.
  • StringBuilder中的方法都没有使用了synchronized修饰符,不安全,但是性能较高.
  • StringBuffer和StringBuilder都表示可变的字符串,功能方法都是相同的,常用于拼接字符串。

3、线程生命周期

1、线程的创建可以使用Thread.new,同样可以以同样的语法使用Thread.start 或者Thread.fork这三个方法来创建线程。

2、创建线程后无需启动,线程会自动执行。

3、Thread 类定义了一些方法来操控线程。线程执行Thread.new中的代码块。

4、线程代码块中最后一个语句是线程的值,可以通过线程的方法来调用,如果线程执行完毕,则返回线程值,否则不返回值直到线程执行完毕。

5、Thread.current 方法返回表示当前线程的对象。 Thread.main 方法返回主线程。

6、通过 Thread.Join 方法来执行线程,这个方法会挂起主线程,直到当前线程执行完毕。

4、实操

1)得到当前线程的名字
package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class ThreadTest {
    public static void main(String[] args) {
        //currentThread()返回当前线程 getName()获得当前线程的名字
        System.out.println(Thread.currentThread().getName())
    }
}

输出: main

2)开启线程(继承).start();
package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class MyThread extends Thread {
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我是" + Thread.currentThread().getName());
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H1Zeqc1t-1604830688309)(E:\day++\day13\设计模式.assets\image-20201107230139575.png)]

4)修改ThreadTest
package xinzhi
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我是" + Thread.currentThread().getName());
        }
    }
}

无序的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gMe8RZik-1604830688312)(E:\day++\day13\设计模式.assets\image-20201107230609998.png)]

5)调用run();,相当于没有开辟新线程,直接调用的主方法
MyThread myThread = new MyThread();
myThread.run();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQ6v0Mdc-1604830688315)(E:\day++\day13\设计模式.assets\image-20201107230748757.png)]

6)再次开辟一条新线程(多线程)
        MyThread myThread = new MyThread();
        myThread.start();
        MyThread myThread2 = new MyThread();
        myThread.start();

无序的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPtw6ZY9-1604830688320)(E:\day++\day13\设计模式.assets\image-20201107231244199.png)]

7)开多线程
package xinzhi;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class MyRun implements Runnable {

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我是" + Thread.currentThread().getName());
        }
    }
}

package xinzhi;
public class MyThread extends Thread {
    public MyThread(){}		//空参构造
    public MyThread(String name) {	//构造方法,传线程的名字
        super(name);
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我是" + Thread.currentThread().getName());
        }
    }
}

package xinzhi;
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread = new MyThread("myThreadde的线程,一号线程");
        myThread.start();

        MyThread myThread2 = new MyThread("myThreadde2的线程,二号线程");
        myThread2.start();

        Thread MyThread3 = new Thread(new MyRun(),"run接口的线程,三号线程");
        MyThread3.start();

        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我是" + Thread.currentThread().getName());
        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e21zeiew-1604830688322)(E:\day++\day13\设计模式.assets\image-20201107233358421.png)]

5、初涉线程安全

拿到下标——赋值——下标+1

package xinzhi;
import java.util.ArrayList;
import java.util.List;

public class ThreadTest {
    public static List<Integer> LIST = new ArrayList<>();

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Thread thread = new Thread(new MyRun());
            thread.start();
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("——————————————LIST共有" +LIST.size() + "个数据");
    }
}

package xinzhi;

public class MyRun implements Runnable {

    @Override
    public void run() {
        System.out.println("添加了一个数据");
        for (int i = 0; i < 100; i++) {
            ThreadTest.LIST.add(i);
        }
}        

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QX19iCtK-1604830688324)(E:\day++\day13\设计模式.assets\image-20201108000217499.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PBXfhPGL-1604830688325)(E:\day++\day13\设计模式.assets\image-20201108000251051.png)]

此时线程不安全

    public static List<Integer> LIST = new Vector<>();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o4l5LAuN-1604830688327)(E:\day++\day13\设计模式.assets\image-20201108001409893.png)]

此时线程安全

三、初涉异常

1、异常产生的原因及使用原则

在 Java 中一个异常的产生,主要有如下三种原因:

  1. Java 内部错误发生异常,Java 虚拟机产生的异常。
  2. 编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等。这种异常称为未检査的异常,一般需要在某些类中集中处理这些异常。
  3. 通过 throw 语句手动生成的异常,这种异常称为检査的异常,一般用来告知该方法的调用者一些必要的信息。

Java 通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。

我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。

Java 异常强制用户考虑程序的强健性和安全性。异常处理不应用来控制程序的正常流程,其主要作用是捕获程序在运行时发生的异常并进行相应处理。编写代码处理某个方法可能出现的异常,可遵循如下三个原则:

  1. 在当前方法声明中使用 try catch 语句捕获异常。
  2. 一个方法被覆盖时,覆盖它的方法必须拋出相同的异常或异常的子类。
  3. 如果父类抛出多个异常,则覆盖方法必须拋出那些异常的一个子集,而不能拋出新异常。

2、异常的继承关系:

img

3、异常的执行流程图:

img

try{    
    // 可能产生异常的语句 
}catch(Exception1 e1){    
    // 处理语句1 
}catch(Exception2 e2){    
    // 处理语句2 
}

四、计算每个单词出现的次数

package xinzhi;
import java.util.HashMap;
import java.util.Map;
/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class Test5 {
    public static void main(String[] args) {
        String content = "aa bb cc Hello aa bb cc World" +
                " AA BB CC hello AA BB CC world";
        content = content.toLowerCase();	//首先将所有字母大写,以便做统计
        String[] words = content.split(" ");	//将字符串打乱成数组
        Map<String,Integer> result = new HashMap<>(16);	//存进hashmap里,给一个初始的长度16
        for (String word : words) {						//遍历所有单词
            if (result.containsKey(word)){				//判断result里是否有这个单词,有就+1
                result.put(word,result.get(word) + 1);
            }else {
                result.put(word,1);				//没有就输出这个值
            }
        }
        for (Map.Entry<String,Integer> entry : result.entrySet()){
            System.out.println(entry.getKey() + "出现" + entry.getValue() + "次");
        }

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WYepN8sl-1604830688330)(E:\day++\day13\设计模式.assets\image-20201107160329694.png)]

五、归并和效率

package xinzhi;

/**
 * 2020/11/7
 * @author cqmfx(阡陌飞絮)
 */
public class Study {
    public static void main(String[] args) {
        int [] arr1 = {1,7,9,12,15,23};
        int [] arr2 = {2,8,10,11,12,13};
        //把两个有序数组合并成一个数组,还有序
        int[] concat = concat (arr1,arr2);	//将两个数组用concat拼起来
        for (int i : concat){			
            System.out.println(i + " ");	//输出归并后的数组
        }
    }

    private static int[] concat(int[] arr1, int[] arr2) {	
        int left = 0;		//设置arr1的首下标
        int right = 0;		//设置arr2的首下标
        int[] temp = new int[arr1.length + arr2.length];	//设置新数组的长度

        for (int i = 0; i < temp.length; i++) {			//边进行遍历边进行归并
            if (left < arr1.length && right < arr2.length){	//判断边界,超出跳出循环
                if (arr1[left] < arr2[right]){			//arr1的下标比arr2的大
                   temp[i] = arr1[left];				//则将此时arr1的值放到新数组里
                    left++;								//arr1指针left下标往后移
                }else {									//反之
                    temp[i] = arr2[right];				//则将此时arr2的值放到新数组里
                    right++;							//arr2指针right下标往后移
                }
            }else if (left < arr1.length){
                temp[i] = arr1[left];
                left++;
            }else if (right < arr2.length){
                temp[i] = arr2[right];
                right++;
            }
        }
        return temp;									//返回新数组temp
    }

}
           left++;								//arr1指针left下标往后移
                }else {									//反之
                    temp[i] = arr2[right];				//则将此时arr2的值放到新数组里
                    right++;							//arr2指针right下标往后移
                }
            }else if (left < arr1.length){
                temp[i] = arr1[left];
                left++;
            }else if (right < arr2.length){
                temp[i] = arr2[right];
                right++;
            }
        }
        return temp;									//返回新数组temp
    }

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值