首页 > 技术文章 > JavaSE学习笔记14:日期类、数字类、随机数与枚举

Sona-36D 2020-11-02 14:55 原文

日期类

java中对日期的处理

这个案例主要掌握:

  1. 知识点1:怎么获取系统当前时间
  2. 知识点2:String ---> Date
  3. 知识点3:Date ---> String
package se2.date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest01 {
    public static void main(String[] args) throws Exception {
        //获取系统当前时间(精确到毫秒)
        //直接调用无参数构造方法就行
        Date nowTime = new Date();
        //java.util.Date类的toString方法已经被重写了
        //输出的不是对象的内存地址,应该是一个日期字符串
        System.out.println(nowTime);//Mon Nov 02 10:58:45 CST 2020

        //日期格式化
        //将日期类型Date,按照指定的格式进行转换:Date -转换成具有一定格式的日期字符串-> String
        //SimpleDateFormat是java.text包下的,专门负责日期格式化的
        //SimpleDateFormat sdf = new SimpleDateFormat(日期格式);
        /**
         * yyyy年、MM月、dd日、HH时、mm分、ss秒、SSS毫秒
         * (毫秒3位,最高999,1000毫秒代表1秒)
         */
        //注意:在日期格式中,除了y、M、d、H、m、s、S这些字符不能随便写,剩下的符号格式自己随意组织
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
        String nowTimeStr = sdf.format(nowTime);
        System.out.println(nowTimeStr);//2020-11-02 11:09:45:212

        //假设现在有一个日期字符串String,怎么转换成Date类型?
        String time = "2008-08-08 08:08:08 888";
        //SimpleDateFormat sdf2 = new SimpleDateFormat("格式日期不能随便写,要和日期字符串格式相同!!!");
        //格式不同会出现如下异常!
        //Exception in thread "main" java.text.ParseException: Unparseable date: "2008-08-08 08:08:08 888"
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        Date dateTime = sdf2.parse(time);
        System.out.println(dateTime);//Fri Aug 08 08:08:08 CST 2008
    }
}

获取1970年至系统当前时间与统计方法耗费的时长:

package se2.date;

public class DateTest02 {
    public static void main(String[] args) {
        //获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数
        //1秒 = 1000毫秒
        long nowTimeMillis = System.currentTimeMillis();
        System.out.println(nowTimeMillis);//1604287537551

         //统计一个方法耗时
         //在调用目标方法之前记录一个毫秒数
        long begin = System.currentTimeMillis();
        print();
        //执行完目标方法之后记录一个毫秒数
        long end = System.currentTimeMillis();
        System.out.println("耗费时长" + (end - begin) + "毫秒");
        //耗费时长16毫秒(每次都不一样)

        /**
         * 简单总结一下System类的相关属性和方法:
         * System.out   【out是System类的静态变量】
         * System.out.println() 【println)()方法不是System类的,是PrintStream类的方法】
         * System.gc()    【建议启动垃圾回收器】
         * System.currentTimeMillis()   【获取自1970年1月1日到系统当前时间的总毫秒数】
         * System.exit(0)   【退出JVM】
         */
    }
    //需求:统计一个方法执行所需要耗费的时长
    public static void print(){
        for (int i = 0; i < 1000; i++) {
            System.out.println("i = " + i);
        }
    }
}

Date的有参构造(过时的除外)

package se2.date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateTest03 {
    public static void main(String[] args) {
        //这个时间是什么时间?
        //1970-01-01 00:00:00 001
        Date time = new Date(1);//注意:参数是一个毫秒

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String strTime = sdf.format(time);
        //东8区,差8个小时,所以是8点
        System.out.println(strTime);//1970-01-01 08:00:00 001

        //获取昨天的此时的时间
        Date time2 = new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24));
        String strTime2 = sdf.format(time2);
        System.out.println(strTime2);//2020-11-01 11:49:10 206
    }
}

数字类(了解)

数字格式化

package se2.number;

import java.text.DecimalFormat;

public class DecimalFormatTest01 {
    public static void main(String[] args) {
        //DecimalFormat专门负责数字格式化的
        //DecimalFormat df = new DecimalFormat("数字格式");
        /**
         * 数字格式有哪些?
         * #    代表任意数字
         * ,    代表千分位
         * .    代表小数点
         * 0    代表不够时补0
         */
        //表示加入千分位,保留2个小数
        DecimalFormat df = new DecimalFormat("###,###.##");
        String s = df.format(1234.5612321);
        System.out.println(s);//1,234.56

        //保留4个小数位,不够补上0
        DecimalFormat df2 = new DecimalFormat("###,###.0000");
        String s2 = df2.format(1234.56);
        System.out.println(s2);//1,234.5600
    }
}

BigDecimal

package se2.number;

import java.math.BigDecimal;
/**
 * BigDecimal属于大数据,精度极高
 * 不属于基本数据类型,属于java对象(引用数据类型)
 *
 * 注意:财务软件double是不够的
 * 问:你处理过财务数据吗?用哪一种类型?
 * 千万别说double!!!说java.math.BigDecimal
 */
public class BigDecimalTest01 {
    public static void main(String[] args) {
        //这个100与200不是普通的100与200,是精度极高的100与200
        BigDecimal v1 = new BigDecimal(100);
        BigDecimal v2 = new BigDecimal(200);
        //求和
        //v1 + v2;这样不行,v1和v2都是引用,不能直接求和
        BigDecimal v3 = v1.add(v2);//调用方法求和
        System.out.println(v3);//300
        //除法
        BigDecimal v4 = v2.divide(v1);
        System.out.println(v4);//2
    }
}

Random(随机数)

package se2.random;

import java.util.Random;

public class RandomTest01 {
    public static void main(String[] args) {
        //创建随机数对象
        Random random = new Random();
        //随机产生一个int类型取值范围的数字
        int num1 = random.nextInt();
        System.out.println(num1);//877745234(随机的)

        //产生0到100之间的随机数,不能产生101
        //这里nextInt翻译为:下一个int类型的数据是101,表示只能取到100
        int num2 = random.nextInt(101);//不包括101
        System.out.println(num2);//89
    }
}

随机数例子

package se2.random;

import java.util.Random;
/**
 * 编写程序,生成5个不重复的随机数,重复的话重新生成
 * 最终生成的5个随机数放到数组中,要求数组中的5个随机数不重复
 */
public class RandomTest02 {
    public static void main(String[] args) {
        //准备一个长度为5的一维数组
        int[] arr = new int[5];//默认值都是0
        for (int i = 0; i < arr.length; i++) {
            arr[i] = -1;
        }
        //以上相当于arr[5] = {-1,-1,-1,-1,-1};

        //创建Random对象
        Random random = new Random();
        //循环,生成随机数
        int index = 0;
        while (index < arr.length){
            //生成随机数
            int num = random.nextInt(10);//只能生成0到9的随机数
            System.out.println("生成的随机数:" + num);
            //判断arr数组中有没有num
            //如果没有num就放进去
            if (!contains(arr,num)){
                arr[index++] = num;
            }
        }
        //遍历以上数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        /*
         * 输出结果:
         * 生成的随机数:7
         * 生成的随机数:8
         * 生成的随机数:4
         * 生成的随机数:4
         * 生成的随机数:9
         * 生成的随机数:1
         * 7 8 4 9 1
         */
    }
    /**
     * 单独编写一个方法:判断数组中是否包含某个元素
     * @param arr 数组
     * @param key 元素
     * @return true表示包含,false表示不包含
     */
    public static boolean contains(int[] arr,int key){
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == key){
                return true;
            }
        }
        return false;
    }
}

枚举

分析以下程序,在设计方面有什么缺陷?(这个案例没有使用枚举)
答:在这个方法的返回值类型上,返回一个int不恰当,既然最后的结果只是成功和失败,最好使用布尔类型。因为布尔类型true和false正好表示两种不同的状态。换成返回Boolean就比这个好,但万一在以后的开发中遇到一个方法的执行结果可能包含多种情况,每一个都是可以一枚一枚都是可以列举出来的,这个布尔类型就无法满足需求了。此时需要使用枚举类型。

package se2.isenum;

public class EnumTest01 {
    public static void main(String[] args) {
        //System.out.println(10 / 0);
        //java.lang.ArithmeticException: / by zero(除数异常,被0除)
        int reValue = divide(10,2);
        System.out.println(reValue == 1 ? "计算成功" : "计算失败");//计算成功

        int reValue2 = divide(10,0);
        System.out.println(reValue2 == 1 ? "计算成功" : "计算失败");//计算失败
    }
    /**
     * 以下程序,计算两个int类型数据的商
     * @param a int类型的数据
     * @param b int类型的数据
     * @return  计算成功返回1,失败返回0
     */
    public static int divide(int a,int b){
        try {
            int c = a / b;
            //程序执行到此处表示以上代码没有发生异常,表示执行成功
            return 1;
        } catch (Exception e){
            //程序执行到此处表示以上程序出现异常
            //表示执行失败
            return 0;
        }
    }
}

以上案例改用枚举

枚举类型的语法:

enum 枚举类型名{
	枚举值1,枚举值2
}
package se2.isenum;
/**
 * 总结:
 *  1.枚举是一种引用数据类型
 *  2.结果只有两种情况的,建议使用布尔类型
 *  结果超过两种并且还是可以一枚一枚列举出来的,建议使用枚举类型
 *  例如:颜色、四季、星期等都可以使用枚举类型
 */
public class EnumTest02 {
    public static void main(String[] args) {
        Result r = divide(10,0);
        System.out.println(r == Result.SUCCESS ? "计算成功" : "计算失败");//计算失败

        Result r2 = divide(10,2);
        System.out.println(r2 == Result.SUCCESS ? "计算成功" : "计算失败");//计算成功
    }

    /**
     * 计算两个int类型数据的商
     * @param a int数据
     * @param b int数据
     * @return Result.SUCCESS表示成功,Result.FAIL表示失败
     */
    public static Result divide(int a, int b){
        try {
            int c = a / b;
            return Result.SUCCESS;
        } catch (Exception e){
            return Result.FAIL;
        }
    }
}
//枚举:一枚一枚可以列举出来的,才建议使用枚举
//枚举编译之后也是生成class文件,枚举也是引用数据类型
//枚举中的每一个值可以看做是常量
enum Result{
    //SUCCESS和FAIL都是枚举Result类型中的一个值
    //枚举中的每一个值,可以看做是“常量”
    SUCCESS,FAIL
}
package se2.isenum;
/**
 * 四季枚举类型
 */
public enum Season {
    /*
    春夏秋冬
     */
    SPRING,SUMMER,AUTUMN,WINTER
}
package se2.isenum;

public class SwitchTest {
    public static void main(String[] args) {
        //switch语句支持枚举类型,也支持Sting、int
        //低版本的JDK只支持int
        switch (Season.AUTUMN){
            //case Season.SPRING:报错
            case SPRING:
                System.out.println("春天");
                break;
            case SUMMER:
                System.out.println("夏天");
                break;
            case AUTUMN:
                System.out.println("秋天");
                break;
            case WINTER:
                System.out.println("冬天");
                break;
        }
        //输出秋天
    }
}
package se2.isenum;
/**
 * 颜色枚举类型
 */
public enum Color {
    /*
    颜色值
     */
    RED,BLUE,YELLOW,BLACK
}

推荐阅读