学习日志 Day15

Day15

一、Random类

Random类主要是生成随机数。

Random类是专门用于生成一个伪随机数的类,其产生的随机数是根据种子和顺序决定的;ThreadLocalRandom类是Java 7新增的一个类,它是Random的增强版。在并发访问的环境下,保证系统具有更好的线程安全性。Random类有两个构造器:

1、Random():创建一个新的随机数生成器。

2、Random(long seed):使用单个long种子创建一个新的随机数生成器。

1.1基本用法:

1.随机生成int取值范围内的数

int num1 = ran.nextInt();
System.out.println(num1);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zsRnFyK4-1652098417860)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509182048506.png)]

2.随机出int类型0~9的数字

int num2 = ran.nextInt(10);//底层原理:随机获取正整数的数字%10
System.out.println(num2);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y85WFu60-1652098417862)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509182235453.png)]

3.随机出double取值范围内的数据

double num3 = ran.nextDouble();
System.out.println(num3);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jb3QTiSO-1652098417863)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509182409357.png)]

4.随机出boolean类型的值

boolean bool = ran.nextBoolean();
System.out.println(bool);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BL1j5Mmt-1652098417863)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509182500032.png)]

1.2应用 – 点名器

将所有的学生姓名放在一个数组内,数组是已知的长度,长度为学生的个数,通过生成随机数去匹配学生在数组的下标,即可找到随机的学生。

public static void main(String[] args) {

    String[] names = {"罗菌鱼","张三","李四","王二麻子","赵五","钱六"};

    Random ran = new Random();
    int index = ran.nextInt(names.length);

    System.out.println(names[index]);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96C8IIp4-1652098417864)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509183035431.png)]

1.3种子数

种子数固定,随机出的数字就是固定的

public class Random {
    
    public Random() {
        //调用本类其他的构造方法
        this(seedUniquifier() ^ System.nanoTime());
    }
    
    private static long seedUniquifier() {
   
        for (;;) {
            //获取了一个值
            long current = seedUniquifier.get();
            //算法
            long next = current * 181783497276652981L;
            //判断next达到某个条件后,返回数据
            if (seedUniquifier.compareAndSet(current, next))
                return next;//返回了一个较为随机的值
        }
    }
    
	//有参构造 -- 传入的数据是种子数
    public Random(long seed) {
        if (getClass() == Random.class)
            this.seed = new AtomicLong(initialScramble(seed));
        else {
            // subclass might have overriden setSeed
            this.seed = new AtomicLong();
            setSeed(seed);
        }
    }
    
}

二、Runtime类

含义:代表着Java的运行环境(JRE、JVM)

常用方法:

  1. availableProcessors():获取处理数
  2. maxMemory():获取最大内存数,单位为字节单位
  3. freeMemory():获取闲置内存数(字节)
public static void main(String[] args) {

    //获取运行时类的对象
    Runtime run = Runtime.getRuntime();

    System.out.println("获取处理数:" + run.availableProcessors());//8
    System.out.println("获取最大内存数(字节):" + run.maxMemory());
    System.out.println("获取闲置内存数(字节):" + run.freeMemory());

}

2.1消耗时长和消耗内存 考虑一段代码的效率

public static void main(String[] args) {

    Runtime runtime = Runtime.getRuntime();
    long startMemory = runtime.freeMemory();
    long startTime = System.currentTimeMillis();
    String str = "甜甜";
    for (int i = 0; i < 10000; i++){
        str += "的冰激凌";
        //str = new StringBuilder(str).append("拍电影").toString();
    }
    long endMemory = runtime.freeMemory();
    long endTime = System.currentTimeMillis();

    System.out.println("消耗时长:" + (endTime - startTime));
    System.out.println("消耗内存:" + (startMemory - endMemory));

    System.out.println("-------------------");

    long startMemory1 = runtime.freeMemory();
    long startTime1 = System.currentTimeMillis();
    StringBuilder stringBuilder = new StringBuilder("苦苦");
    for (int i = 0; i < 10000; i++){
        stringBuilder.append("的巧克力");
    }
    long endMemory1 = runtime.freeMemory();
    long endTime1 = System.currentTimeMillis();

    System.out.println("消耗时长:" + (endTime1 - startTime1));
    System.out.println("消耗内存:" + (startMemory1 - endMemory1));

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aLmqxSrQ-1652098417866)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509185056570.png)]

2.2设计模式之单例模式

前言:new对象的过程叫做实例化

理解:该类的对象只有一个

单例模式:

  • 私有化构造方法
  • 创建静态常量:private static final A a = new A();
  • 添加静态的get方法
public class A {
	
	/**
	 * 为什么使用private修饰:
	 * 		私有化属性,并且添加get方法让外界获取a对象
	 * 为什么使用static修饰:
	 * 		使用到该类,该类的class文件加载到方法区时(类加载机制),就会在静态区中创建A类的对象
	 * 		getInstance方法是静态方法,静态方法只能调用静态属性
	 * 为什么使用final修饰:
	 * 		应该该对象创建后,不允许外界改变
	 */
	private static final A a = new A();

	private A() {
	}
	
	public static A getInstance(){
		return a;
	}
}

**问题1:**为什么使用private修饰:

  • 私有化属性,并且添加get方法让外界获取a对象

**问题2:**为什么使用static修饰:

  • 使用到该类,该类的class文件加载到方法区时(类加载机制),就会在静态区中创建A类的对象
  • getInstance方法是静态方法,静态方法只能调用静态属性

问题3: 为什么使用final修饰:

  • 应该该对象创建后,不允许外界改变
public static void main(String[] args) {
    //单例模式
    Runtime run = Runtime.getRuntime();
    Calendar calendar = Calendar.getInstance();
    A a = A.getInstance();
}

三、System类

知识点:研究System类的属性

(注意流的方向是站在程序的角度去看待)

输入流:

//系统标准的输入流(方向:控制台->程序)
InputStream in = System.in;
Scanner scan = new Scanner(in);
String str = scan.next();
scan.close();//关闭资源

//程序标准的错误输出流(方向:程序->控制台)
PrintStream err = System.err;//err -- error错误
err.println(str);

输出流:

//程序标准的输出流(方向:程序->控制台)
PrintStream out = System.out;
out.println(str);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrgD6CSf-1652098417867)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509190726326.png)]

3.1研究System的out和err

System.out.println("小明");
System.err.println("小红");
System.out.println("小强");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLhKuZcb-1652098417868)(F:\java_learing\doc\Weeks04\Day15\system.png)]

**注意:**err是一个线程里的代码、out是另一个线程里的代码

3.2、System的常用方法

  • getProperties():获取系统配置文件对象
  • getProperty():通过键找到配置文件中对应的值
//获取系统配置文件对象
Properties properties = System.getProperties();
System.out.println(properties);

//通过键找到配置文件中对应的值
String value = System.getProperty("os.name");
System.out.println(value);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ek5uJhd9-1652098417869)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509191449831.png)]

  • arraycopy():用于删除数组元素,原数组,开始下标,原数组,开始下标,拷贝次数
int[] is = {1,2,3,4,5,6,7,8,9};

System.out.println("原数组:" + Arrays.toString(is));
System.arraycopy(is, 3, is, 2, is.length - 3);//原数组,开始下标,原数组,开始下标,拷贝次数

is[is.length-1] = 0;//将0赋值给最后下标的位置
System.out.println("删除后:" + Arrays.toString(is));
  • src表示源数组
  • srcPos表示源数组中拷贝元素的起始位置。
  • dest表示目标数组
  • destPos表示拷贝到目标数组的起始位置
  • length表示拷贝元素的个数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLj9z0C7-1652098417869)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509192600406.png)]

四、大数值运算

4.1整数大数值运算类

常用的方法:

  • .add:加法
  • .subtract:减法
  • .multiply:乘法
  • .divide:除法
BigInteger bigInteger1 = new BigInteger("1234567890147");
BigInteger bigInteger2 = new BigInteger("1234567890147");
BigInteger add = bigInteger1.add(bigInteger2);
System.out.println("加法:" + add);

BigInteger subtract = bigInteger1.subtract(bigInteger2);
System.out.println("减法:" + subtract);

BigInteger multiply = bigInteger1.multiply(bigInteger2);
System.out.println("乘法:" + multiply);

BigInteger divide = bigInteger1.divide(bigInteger2);
System.out.println("除法:" + divide);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccmvNlsV-1652098417870)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509192848609.png)]

4.2注意:小数在底层使用二进制存储时会失去精度,千万不能直接做运算

在数据敏感的项目中不能直接进行运算,因为会损失精度,因此会使用到BigDecimal。

BigDecimal bigDecimal1 = new BigDecimal("0.5");
BigDecimal bigDecimal2 = new BigDecimal("0.4");

BigDecimal add = bigDecimal1.add(bigDecimal2);
System.out.println(add);

BigDecimal subtract = bigDecimal1.subtract(bigDecimal2);
System.out.println(subtract);

BigDecimal multiply = bigDecimal1.multiply(bigDecimal2);
System.out.println(multiply);

BigDecimal divide = bigDecimal1.divide(bigDecimal2);
System.out.println(divide);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9AlvluS-1652098417871)(C:\Users\Hp\AppData\Roaming\Typora\typora-user-images\image-20220509193222468.png)]

注意:小数在底层使用二进制存储时会失去精度,千万不能直接做运算

BigDecimal big1 = new BigDecimal("10");
BigDecimal big2 = new BigDecimal("3");

BigDecimal divide = big1.divide(big2, 3, BigDecimal.ROUND_HALF_UP);//(除数,保留小数位,进制模式)
System.out.println("除法:" + divide);

五、枚举

5.1引入

需求:编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)

public static final Season spring = new Season("春天", "万物复苏");
public static final Season summer = new Season("夏天", "烈日炎炎");
public static final Season autumn = new Season("秋天", "硕果累累");
public static final Season winter = new Season("冬天", "寒风凛冽");

分析:上面并没有使用枚举,这样做一共new了4个对象,对于代码的可读性以及效率都不是很高,那怎样解决呢?下面开始引入枚举

枚举:枚举是在一定范围内取值,并且这个值必须是枚举类型中的任意一个,并且只能有一个

特点:

  1. 必须在规定范围内取值
  2. 这个值只能取一个
  3. 这个值可以是规定范围内的任意一个

枚举的本质就是一个Java类

SPRING("春天", "万物复苏"),
SUMMER("夏天", "烈日炎炎"),
AUTUMN("秋天", "硕果累累"),
WINTER("冬天", "寒风凛冽");

private String name;
private String info;

枚举类型默认使用public static final 类名 修饰

应用场景:一个类只能有固定的几个对象时,就考虑使用枚举

枚举中常用的方法:

  • Enum.valueOf:通过字符串找到枚举类的某个对象,这里的valueOf是Enum的方法
  • 类名.valueOf:这里的valueOf是父类的方法
//通过字符串找到枚举类的某个对象
Season season1 = Enum.valueOf(Season.class, "spring");
System.out.println(season1);

//通过字符串找到枚举类的某个对象
Season season2 = Season.valueOf("spring");
System.out.println(season2);

//获取该枚举类中所有的对象
Season[] seasons = Season.values();
for (Season season : seasons) {
    //获取枚举对象的名字
    String name = season.name();
    System.out.println(name);
}

5.2状态机

枚举的应用之状态机

//信号灯
public enum Signal {
    RED,YELLOW,GREEN;
}
public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);
    System.out.println("请选择信号灯:RED,YELLOW,GREEN");
    String str = scan.next();
    scan.close();

    //通过字符串找到枚举类的对象
    Signal signal = Signal.valueOf(str);

    String trafficInstruct = getTrafficInstruct(signal);
    System.out.println(trafficInstruct);
}

public static String getTrafficInstruct(Signal signal){
    String instruct = "信号灯故障";

    switch (signal) {
        case RED:
            instruct = "红灯停";
            break;
        case YELLOW:
            instruct = "黄灯请注意";
            break;
        case GREEN:
            instruct = "绿灯行";
            break;
    }
    return instruct;
}

5.3枚举应用之组织枚举

可以将类型相近的枚举通过接口或类组织起来(但是一般用接口方式进行组织)

原因:

  • Java接口在编译时会自动为enum类型加上public static修饰符;
  • Java类在编译时会自动为 enum 类型加上static修饰符;
  • 就是说,在类中组织 enum,如果你不给它修饰为 public,那么只能在本包中进行访问。
enum AddCode {

    ERROR_A(-1,"添加失败 -- 学生信息不合法"),
    ERROR_B(-2,"添加失败 -- 有重复学生"),
    OK(1,"添加成功");

    private int code;
    private String info;
}

enum DeleteCode {

    ERROR_A(-1,"删除失败 -- 学生信息不合法"),
    ERROR_B(-2,"删除失败 -- 没有该学生"),
    OK(1,"删除成功");

    private int code;
    private String info;
}

5.4枚举应用之策略枚举

//工资的枚举
public enum Salary {
    Java(StaffType.teacher),
    Html(StaffType.teacher),
    Python(StaffType.teacher),
    Reception(StaffType.administrative),
    Principal(StaffType.administrative)
        ;

    private StaffType staffType;

    private Salary(StaffType staffType) {
        this.staffType = staffType;
    }

    public double getSalary(double baseSalary, int classHour, double teachingHourSubsidy,
                            double achievements){

        return staffType.calculationSalary(baseSalary, classHour, teachingHourSubsidy, achievements);
    }


    //员工类别
    enum StaffType{

        //匿名内部类的对象: class 匿名类 extends StaffType
        teacher{
            @Override
            public double calculationSalary(double baseSalary, int classHour, double teachingHourSubsidy,
                                            double achievements) {

                //老师的工资:基本工资 + 课时*课时费 + 绩效
                BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));
                BigDecimal big2 = new BigDecimal(String.valueOf(classHour));
                BigDecimal big3 = new BigDecimal(String.valueOf(teachingHourSubsidy));
                BigDecimal big4 = new BigDecimal(String.valueOf(achievements));

                BigDecimal salary = big2.multiply(big3).add(big1).add(big4);

                return salary.doubleValue();
            }
        },
        //匿名内部类的对象: class 匿名类 extends StaffType
        administrative{

            @Override
            public double calculationSalary(double baseSalary, int classHour, double teachingHourSubsidy,
                                            double achievements) {

                BigDecimal big1 = new BigDecimal(String.valueOf(baseSalary));
                BigDecimal big2 = new BigDecimal(String.valueOf(achievements));

                BigDecimal salary = big1.add(big2);
                return salary.doubleValue();
            }
        }
        ;

        /**
		 * 计算工资的方法
		 * @param baseSalary 基本工资
		 * @param classHour 课时
		 * @param teachingHourSubsidy 课时费
		 * @param achievements 绩效
		 * @return 应得工资
		 */
        public abstract double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements);
    }
public static void main(String[] args) {
    /**
		 * 枚举应用之策略枚举
		 * 
		 * 需求:模拟千锋计算工资的场景
		 */

    double salary1 = Salary.Java.getSalary(1300, 84, 15, 1000);
    System.out.println(salary1);

    double salary2 = Salary.Reception.getSalary(500, 0, 0, 10000);
    System.out.println(salary2);
}

teachingHourSubsidy 课时费

   * @param achievements 绩效
   * @return 应得工资
   */
    public abstract double calculationSalary(double baseSalary,int classHour,double teachingHourSubsidy,double achievements);
}

```java
public static void main(String[] args) {
    /**
		 * 枚举应用之策略枚举
		 * 
		 * 需求:模拟千锋计算工资的场景
		 */

    double salary1 = Salary.Java.getSalary(1300, 84, 15, 1000);
    System.out.println(salary1);

    double salary2 = Salary.Reception.getSalary(500, 0, 0, 10000);
    System.out.println(salary2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值