java第一阶段(day11)Utill包常用类

一周总结

异常
1. 什么是异常?
    程序运行期间  出现了不正常的现象。   异常/错误
 2. 异常分类
   编译时异常: 
       IoException
       ParseException
       ClassNotFoundException
       CloneNotSupportedException
       。。。。      
       
   运行时异常  (RuntimeException)
     NullPointerException---->NPE
     
 3.处理异常
    java语言提供异常处理机制  一段程序出现问题 不影响其他程序正常执行
    3.1 捕获异常(真正处理异常的方式)
        try...catch...finally
        何时使用finally?  释放物理资源/释放锁
        try....finally
    3.2  抛出异常  throws   在方法的签名后面使用throws抛出具体的异常类型
         消极处理异常的方式  
         把异常抛出给调用  (没有能力处理的时候)
            
4. throw
    产生异常。 在方法体里面 使用throw 抛出具体的异常对象。  throw  new 异常类构造;
    场景:
      1. 预判 控制程序执行流程
      2. 与自定义异常类的时候
      3. 异常信息的传递  在catch  Casued by
          
    
lang包常用类
  1. 整数缓存池是干吗的?
   池子就是一个数组。 是一个包装类型的数据。
   Byte Short Integer Long Character: -128-127  
   Character: 0-127
   Integer num1 = 200;//自动装箱   Integer.valueOf(100)
   Integer num2 = 200;
 2. 字符串与整数类型之间相互转换实现方式?
    int num = 100;
    num+"";
    String.valueOf(num)
   
    String str = "1234";
    int s = Integer.parseInt(str)
        Long.parseLong();
 

 3. 比较对象一定要重写equlas+hashcode?
      ==   Object.equlas
 4. Object.clone
   protected Object  clone() throws CloneNotSupportedException;
      
 5. 获得Class类对象的方式?
     getClass()
     Class.forName();
     类名.class;

String VS StringBuffer  vs StringBuilder
共同点:  都是代表任意一个字符串的数据。
不同点:
   1.数据是否可变的角度。 String值不可变的。底层是由一个final byte[] 
      StringBuffer/StringBuilder是可变的。执行任意更新功能 都会还原到源对象。
      底层是由一个动态数组维护字符串数据。
      
   2.性能不同。StringBuilder性能最高的  其次是String  最后是StringBuffer
   3.安全角度分析。 
      StringBuffer是线程安全的一个类。底层的所有的功能都使用synchornized
      String: 线程安全的 
      StringBuilder: 线程不安全的
   4. 从内存(拼接)。
      StringBuffer/StringBuilder 永远只有1个变量  内存占用较少。
      String:  +  concat  join 都会产生很多个新的字符串数据  占用内存较多。
      
            
 final  vs finally  vs finalize
 final:是一个修饰符
  1.修饰变量 
  2、修饰类
  3. 修饰方法
  
  finally: 捕获异常。 try...catch...finally
      当有资源需要释放。
      
 finalize: 回收无用对象。不推荐手动调用。 GC会自动执行回收无用引用关联的对象。
  可以回收软 弱 虚引用关联对象。

Util包常用类

都是工具类。会用就可以了。

1.日期时间类

1.1 Date

维护一个特定的日期时间。java.util.Date

//无参构造: 获得当前系统此刻日期时间
Date date = new Date();
System.out.println(date);

Date(long date) //将指定的毫秒数转成特定的日期对象

1. 场景

@Data
public class Employee {

    private Integer id;
    private String name;
    private String phone;
    private Date birthday;
    private Date hireDate;
    private Date createTime;
    private Date updateTime;

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", birthday=" + DateUtil.dateConvertToStr(birthday) +
                ", hireDate=" + DateUtil.dateConvertToStr(hireDate) +
                ", createTime=" + DateUtil.dateConvertToStr(createTime) +
                ", updateTime=" + DateUtil.dateConvertToStr(updateTime) +
                '}';
    }
}

//员工入职: 录入员工信息到公司系统里面
//员工id name age phone 入职时间 生日 新建员工时间  更改员工信息时间  地址

public static void registerEmployee() {
    Scanner input = new Scanner(System.in);
    Employee employee = new Employee();
    System.out.println("请录入员工name:");
    employee.setName(input.nextLine());

    System.out.println("请录入员工phone:");
    employee.setPhone(input.nextLine());

    //录入的字符串数据如何转换成一个Date类型的数据?
    //String 转 Date

    System.out.println("请录入员工生日:");//2020-01-01 12:00:00
    String birthday = input.nextLine();
    employee.setBirthday(DateUtil.strConvertDate(birthday));

    System.out.println("请录入员工入职时间:");//2020-01-01 12:00:00
    String hireDate = input.nextLine();
    employee.setHireDate(DateUtil.strConvertDate(hireDate));

    //System.out.println("请录入新建员工时间:");
    //获得当前此刻的时间即可
    employee.setCreateTime(new Date());

    //能够获得一个完整的员工信息,用户体验感不高
    //看不懂时间
    //只能看懂: 2020-01-01 12:00:00
    System.out.println("注册员工信息成功,信息如下:" + employee.toString());

    input.close();

}

2. 常用方法

public static void test1() {
    //获得当前时间的毫秒数
    Date date = new Date();
    System.out.println(date.getYear() + 1900);//1900
    System.out.println(date.getMinutes());
    System.out.println(date.getHours());
    System.out.println(date.getMonth() + 1);//2
    System.out.println(date.getDate());
    System.out.println(date.getDay());//1 获得这一天是这一周的第几天
    System.out.println(date.getTime());//获得时间毫秒数

    //不推荐使用Date里面的getTime获得毫秒数
    //与对象密切相关
    //推荐
    System.out.println(System.currentTimeMillis());//毫秒数
    System.out.println(System.nanoTime());
}

1.2 LocalDateTime、

jdk1.8+   在java.time.*   全部都是值不可变    任何更新都会产生新的对象  且线程都是安全的

Instant----> 年月日 时分秒

LocalDate   年月日

LocalTime   时分秒

LocalDateTime  年月日 时分秒

1. 场景

@Data
public class UserInfo {

    private Integer id;
    private String name;
    private LocalDate birthday;
    private LocalDateTime hireDate;

    private LocalDateTime createTime;

    //local相关的对象转字符串 就调用这个类里面的format
    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", birthday=" + birthday +
                ", createTime=" + createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
                '}';
    }

    //从前到后:  客户端的数据转换后端的对象----> String转Date/localDate  parse
    //从后往前: 给用户看的时候  ----->Date/localDate转String   format
}

private static void demo1() {
        Scanner input = new Scanner(System.in);
        UserInfo userInfo = new UserInfo();
        System.out.println("请录入用户name:");
        userInfo.setName(input.nextLine());


        //String转LocalDate
        //字符串转jdk1.8+ time包里面的任意一个类  就使用这个类里面parse方法

        System.out.println("请录入用户生日:");
        String birthday = input.nextLine();
        userInfo.setBirthday(LocalDate.parse(birthday));
        System.out.println(userInfo.getBirthday());

        //转:
        System.out.println("请录入用户入职时间:");
        String hireDate = input.nextLine();
        userInfo.setHireDate(LocalDateTime.parse(hireDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        //现在:now
        userInfo.setCreateTime(LocalDateTime.now());//获得的是当前此刻时间

        System.out.println(userInfo.toString());
    }

2. 常用方法

private static void demo2() {

    //1.获得LocalDateTime对象
    //LocalDateTime now = LocalDateTime.now();
   /* System.out.println(now);//2022-02-28T15:10:06.920312800
    System.out.println(LocalDateTime.now(Clock.systemDefaultZone()));
    System.out.println(LocalDateTime.now(Clock.systemUTC()));
    //所有的时区都使用ZoneId代表
    System.out.println(LocalDateTime.now(Clock.system(ZoneId.of("America/Chicago"))));
    //通过指定的时区获得时间,不太推荐local一些类  本地时间
    System.out.println(ZonedDateTime.now(ZoneId.of("America/Chicago")));*/

    //2020-10-01 12:30:30
    LocalDateTime time = LocalDateTime.of(2022, Month.JANUARY, 1, 12, 30, 30);
    System.out.println(time);

    //值不可变
    //TemporalAmount都是接口-----> Duration  Period  时间间隔
    // default Temporal plus(TemporalAmount amount) {
    //TemporalUnit: 时间单位  ChronoUnit
    //public static Duration of(long amount, TemporalUnit unit) {
    //time = time.plus(Period.ofYears(10));
    //time = time.plus(10, ChronoUnit.YEARS);
    //time = time.plusYears(1);
    //time = time.minusMonths(2);

    LocalDateTime now = LocalDateTime.now();
    //获得2个日期间隔的天数
    //Temporal: 接口 代表日期时间
    //TemporalUnit: 日期单位
    //public long until(Temporal endExclusive, TemporalUnit unit) {
    long durationDays = Math.abs(now.until(time, ChronoUnit.DAYS));
    System.out.println(durationDays);

    System.out.println(now.getMonthValue());
    System.out.println(now.getMonth());
    System.out.println(now.getDayOfWeek());
    System.out.println(now.getDayOfMonth());
}

1.3 Calendar日历类

  private static void demo3() {
        //1.获得Calendar 类对象
        Calendar calendar = Calendar.getInstance();//多态  获得系统此刻日历信息
        System.out.println(calendar);
        //获得具体时间单位数据----> get
        //Date date = calendar.getTime(); calendar转换成Date类对象
        System.out.println(calendar.get(Calendar.YEAR));
//        System.out.println(calendar.get(Calendar.MONTH)+1);
//        System.out.println(calendar.get(Calendar.DATE));
//        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//        System.out.println(calendar.get(Calendar.HOUR));
//        System.out.println(calendar.get(Calendar.MINUTE));
//        System.out.println(calendar.get(Calendar.SECOND));

        //修改年份值为2021
        //年份-1
        //calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)-1);
//        calendar.set(Calendar.MONTH,Calendar.MAY);
       /* calendar.add(Calendar.YEAR,2);
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH)+1);*/

        //calendar.setTime(new Date());//将指定的date数据转换成Calander对象

        //打印输出指定年份指定月份的完整的日历信息
        //2022-02
        //获得这个月份最大的天数
        //calendar.set(Calendar.MONTH,Calendar.MARCH);
        int maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println(maximum);
        //周日  周一
        //获得这一天是这一周的第几天
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println(day);
    }

2.格式化类

abstract  class  Format -----> java.text.Format

DateFormat , 格式化日期
   SimpleDateFormat 子类
   
MessageFormat ,格式化字符数据
NumberFormat 格式化数字

2.1  日期格式化 DateFormat

public abstract class DateFormat
extends Format

public class SimpleDateFormat
extends DateFormat

常用构造:
   SimpleDateFormat(String pattern) 
   模式:

public class DateUtil {

    private DateUtil() {
    }

    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

    //String 转  Date
    public static Date strConvertDate(String dateStr) {
        Objects.requireNonNull(dateStr);
        if (dateStr.isBlank()) {
            throw new RuntimeException("字符串数据为空串");
        }
        //转----> 使用日期格式化类转换数据
        DateFormat dateFormat = new SimpleDateFormat(PATTERN);
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();//字符串时间无法满足pattern模式的要求(字符串时间内容>=pattern)
        }
        return null;
    }

    //Date转String
    public static String dateConvertToStr(Date date) {
        if (date == null) {
            return "";
        }
        Objects.requireNonNull(date);
        DateFormat dateFormat = new SimpleDateFormat(PATTERN);
        return dateFormat.format(date);
    }

}

SimpleDateFormat这个类线程不安全。不能作为成员变量使用、

2.2 数值格式化 NumberFormat

DecimalFormat

DecimalFormat(String pattern)

private static void demo3() {
    //3.对钱数值进行格式化
    double money = 16637743645556364353534535.6787346;
    System.out.println(money);
    NumberFormat numberFormat = new DecimalFormat(",###.###");
    System.out.println(numberFormat.format(money));

    //存储用户余额: 将钱全部转成分
    //转成2部分:
    //在开发中  余额使用什么类型维护?  BigDecimal---->小数运算
    //System.out.println(0.1+0.2);
    //System.out.println(0.3/0.1);

    BigDecimal num1 = new BigDecimal("0.3");
    BigDecimal num2 = new BigDecimal("0.1");
    System.out.println(num1.divide(num2));

    BigDecimal num3 = BigDecimal.valueOf(0.2);
    System.out.println(num3.add(num2));


}

private static void demo2() {
    //2. 将数据转换成百分制的数字 小数点之后保留3个数字
    double num = 0.1234567;
    NumberFormat numberFormat = new DecimalFormat(".###%");
    String result = numberFormat.format(num);
    System.out.println(result);
}

private static void demo1() {
    //1. 保留小数点后面指定的位数
    double num = 1100.567895;
    //System.out.println(Math.round(num));
    //格式化数字类  NumberFormat
    //NumberFormat numberFormat = new DecimalFormat("0000000.000");
    NumberFormat numberFormat = new DecimalFormat("######.###");
    String result = numberFormat.format(num);
    System.out.println(result);

    //String转Double
    System.out.println(Double.parseDouble(result));
}

2.3 DateTimeFormatter

jdk1.8+提供的新的转换日期的格式化类。 这个类线程安全  且值不可变。

常用方法:

static DateTimeFormatter ofPattern(String pattern)

3. 随机数类 Random

java.util.Random的java.util.Random是线程安全的。 但是,跨线程的同时使用java.util.Random实例可能会遇到争用,从而导致性能下降。 在多线程设计中考虑使用ThreadLocalRandom 。

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

private static void demo1() {
    ThreadLocalRandom random = ThreadLocalRandom.current();
    int num = random.nextInt(1000, 10000);
}

private static void demo() {
    //循环5次 在每次循环里面获得5个随机数字  1000-10000
    //预测到随机数是多少? 可以预测 指定seed
    for (int i = 1; i <= 5; i++) {
        Random random = new Random(1000);
        for (int j = 1; j <= 5; j++) {
            //获得随机数
            int randomNum = (random.nextInt(9000) + 1000);
            System.out.print(randomNum + "\t");
        }
        System.out.println();
    }
}

4. 编码/解码类

加密。 用户注册/路径/接口路径/参数  不能明文暴露。  必须密文传递/密文存储

解密。

http://book.zongheng.com/chapter/1182914/67622452.html
https://read.qidian.com/chapter/YPMLlm2xwADH0qbqCO3QNg2/pk97yW9jK2dMs5iq0oQwLQ2/

4.1 Base64

是完全可逆。

//登录: 再加密  与加密之后数据进行比较
private static void demo2() {
    String pass = "MTIzNHpoYW5nc2FuJSQjQCE=";

    //1.获得Base64解码器
    Base64.Decoder decoder = Base64.getDecoder();
    byte[] bytes = decoder.decode(pass);
    //字节数组转String
    String s = new String(bytes);
    System.out.println(s);
}

//Base64是完全可逆的。
//加盐
private static final String SALT = "zhangsan%$#@!";

//模拟注册
private static void demo1() {
    String pass = "1234";
    pass = pass + SALT;
    //Base64(使用一些字母和数字和特殊符号组成)
    //编码/加密----> 编码器
    //1.获得编码器
    Base64.Encoder encoder = Base64.getEncoder();
    //2.对文本数据进行加密处理
    //将字符串转换成字节数组
    String encodePass = encoder.encodeToString(pass.getBytes());
    System.out.println(encodePass);//MTIzNA==
}

4.2 MD5

是一种不可逆的加密算法。信息摘要算法(MD5 SHA-1 SHA-256)   Message-Digest Algorithm

1234====>  81dc9bdb52d04dc20036dbd8313ed055

将字符串转换成16进制字符组成的文本数据。

public class MD5Util {

    private MD5Util() {
    }

    public static String md5(String sourceStr) {

        Objects.requireNonNull(sourceStr);
        StringBuilder builder = new StringBuilder();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(sourceStr.getBytes());
            byte[] bytes = messageDigest.digest();
            for (byte aByte : bytes) {
                builder.append(byteToHex(aByte));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return builder.toString().toUpperCase();
    }

    private static final char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static String byteToHex(byte aByte) {
        int num = aByte;
        if (num < 0) {
            num += 256;
        }
        int low = num / 16;
        int high = num % 16;
        return array[low] + "" + array[high];
    }
}

5.课堂练习

1.旧版

1.日期类

1.1Date

1.2Calendar

特定的日历的时间。 抽象类

Calender类里的常用方法--set()/get()/setTime()/getTime()/add()

public class CalenderDemo {
    public static void main(String[] args) {
        //1.创建Calender对象
        Calendar calendar = Calendar.getInstance();       //拿到系统当前此刻的日历时间
        System.out.println(calendar);

        //2.获得具体时间单位的数据  get(int filed属性)  属性可用Calender类里的属性
        System.out.println(calendar.get(Calendar.YEAR));  //2022
        System.out.println(calendar.get(Calendar.MONTH)+1); //2       月份需要加1,才是当前月份

        System.out.println(calendar.get(Calendar.DAY_OF_MONTH));  //27
        System.out.println(calendar.get(Calendar.DATE));  //27

        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));  //1    这一周的第五天,国外周日是第一天

        //3.与date的相互转换
        //Calender转date    用的getTime(),返Date
        Date time = calendar.getTime();
        System.out.println(time); //Sun Feb 27 12:27:50 CST 2022

        //date转Calender   首先得有Date对象  然后还要有Calender实例  再用Calender的setTime(Date date)方法
        Date date = new Date();
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date);

        //4.修改时间  set方法  或者add方法
        //使用set
        calendar.set(2020,Calendar.MONTH,1,12,30,30);
        //月份不要写死,想改成2月,就得写成1月。最好用其常量维护(1-12月份是0-11的标识)
        //之后查看日期,将变为修改后的日期

        //add方法 add(int field,int amout) 现在要求从当前时间往后加10天
        calendar.add(Calendar.DATE,10);
        //若用set去做,set(int field,int value)
        calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+10);
        
    }
}

1.3LocalDate/LocalDateTime

员工信息

public class Emp {
    private Integer id;
    private LocalDate hireDate;  //员工出生时间
    private LocalDate birthday;  //员工生日
    private LocalDateTime create_time;  //员工创建时间
    private LocalDateTime update_time; //员工信息修改时间

}

LocalDate表示的年月日操作LocalDateTime时分秒

public class LocalDateDemo {
    public static void main(String[] args) {
        //LocalDate 用final修饰(没有子类),构造私有(不能new)  肯定用静态方法拿
        //1.获得LocalDate实例  用LocalDate的静态方法,很多方法都返的实例   now()   或者   of
        LocalDate now = LocalDate.now();
        System.out.println(now);  //2022-02-27     获得当前时间

        //of(年,月,日)  一个全是int,一个月是Month类(枚举类),推荐用常量去写,不要写死
        LocalDate localDate = LocalDate.of(2022, Month.MAY, 1);
        System.out.println(localDate);  //2022-05-01

        //2.拿年,月,日
        System.out.println(now.getYear());         //2022
        System.out.println(now.getMonth());        //FEBRUARY  拿枚举的
        System.out.println(now.getMonthValue());   //2    拿整型的
        System.out.println(now.getDayOfMonth());   //27

        //3.修改时间  plus加  minus减
        now.plusDays(20);    //这样做,不会加20天,值不可变。要想改变,要重新赋值
        System.out.println(now);  //2022-02-27
        now = now.plusDays(20);  //和String一样
        System.out.println(now);  //2022-03-19

        //看plus带两参数的  plus(amountToAdd , TemporalUnit一个接口,用于限定)
        now = now.plus(20, ChronoUnit.DAYS);
        System.out.println(now);  //2022-04-08

        //plus带一个参的 plus(TemporalAmount一个接口,时间间隔)
        now = now.plus(Period.ofDays(20));
        System.out.println(now);  //2022-04-28

        //4.求两个日期的时间间隔  until方法
        //until(ChronoLocalDate)
        Period period = localDate.until(now);
        System.out.println(period);  //P-3D   (Y年  M月  D日)

        //until(Temporal ,TemporalUnit )
        long days = now.until(localDate, ChronoUnit.DAYS);
        System.out.println(days);  //3

    }
}

1.4 Instant

Instant 瞬时点

public class InstantDemo {
    public static void main(String[] args) {
        Instant now = Instant.now();  //拿的UTC(格林尼日时间)的时间,与中国时间差8小时
        System.out.println(now);  //2022-02-27T06:28:56.359890900Z

        //求中国时间
        now = now.plus(Duration.ofHours(8));   //操作年月日用period   时分秒用Duration
        System.out.println(now);  //2022-02-27T14:30:25.811234200Z

        //加时间
        now = now.plusSeconds(Duration.ofHours(8).getSeconds()) ;  //括号里是8小时转秒数
    }
}

2.格式化类Format

2.1格式化日期类DateFormat

1.SimpleDateFormat

2.DateTimeFormatter

DateTimeFormatter格式化日期

@Data
public class DateTimeFormatterDemo {

    private static  final  String PATTERN = "yyyy-MM-dd HH:mm:ss";       //创建时间格式
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(PATTERN);
    public static void main(String[] args) {

        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);  //2022-02-27T14:42:58.061979600

        //不希望有T,和毫秒数,只要年月日和时分秒
        //localDateTime 转String
        String format = FORMATTER.format(localDateTime);
        System.out.println(format);   //2022-02-27 14:51:10

        System.out.println("----------------------------------------");
        //String转LocalDateTime
        String create_time = "2022-02-27 14:51:10";
        Emp emp = new Emp();
        //emp.setCreate_time(create_time);  这里不能直接转

        //字符串转哪一个Local对象,就调用这个类里的parse方法
        LocalDateTime localDateTime1 = LocalDateTime.parse(create_time,FORMATTER);   //必须用parse()带两个参数的
        emp.setCreate_time(localDateTime1);
        System.out.println(localDateTime1);  //2022-02-27T14:51:10

        System.out.println("============================================");
        //String转LocalDate   也是parse,一个参两个参都行
        String birthday = "2021-01-01";
        emp.setBirthday(LocalDate.parse(birthday));
        System.out.println(emp);

    }
}

2.2格式化数字NumberFormat

一般针对小数和整数格式化,结果为字符串类型

何时用:1.保留小数点后几位 2.将小数转换成百分制 3.格式化钱数

public class DecimalDemo {
    public static void main(String[] args) {
        //保留两位小数
        NumberFormat numberFormat = new DecimalFormat(".00");    //.##也可以
        NumberFormat numberFormat1 = new DecimalFormat("00000.00"); //代表小数点前有5个数字
        NumberFormat numberFormat2 = new DecimalFormat("#####.00");

        double num = 100.56789;
        String result = numberFormat.format(num);   //结果为字符串类型
        System.out.println(result);       //100.57

        String result1 = numberFormat1.format(num);
        System.out.println(result1);    //00100.57    不够用0填充

        String result2 = numberFormat2.format(num);
        System.out.println(result2);       //100.57
    }
}

public class DecimalDemo2 {
    public static void main(String[] args) {
        //百分数   在格式化对象时加个百分号即可
        double num = 0.56789;
        NumberFormat numberFormat = new DecimalFormat(".##%");   //格式化对象
        String result = numberFormat.format(num);
        System.out.println(result);  //56.79%  (四舍五入了)

        //格式化金钱   每三个一个逗号   若钱太大,还会从小数点分成两部分
        double money = 18546546465.32165416565;
        NumberFormat numberFormat1 = new DecimalFormat("#,###.#### ");   //格式化对象
        String result1 = numberFormat1.format(money);
        System.out.println(result1);  //18,546,546,465.3217

    }
}

3.随机数类 Random

ThreadLocalRadom 随机数 是Random的子类

public class RandomDemo {
    public static void main(String[] args) {

        for(int i=0;i<5;i++){
            Random random = new Random();   //seed:当前纳秒数(时间会一直变)   无参
            for(int j= 0;j<5;j++){
                int num = random.nextInt(100);  //产生0-100之间的随机整数,包头不包尾
                System.out.print(num+",");
            }
            System.out.println();
        }

        System.out.println("-----------------");
        //伪随机:种子一致时,数值可预测
        for(int i=0;i<5;i++){
            Random random1 = new Random(100);   //seed:100            有参
            for(int j= 0;j<5;j++){
                int num = random1.nextInt(100);  //产生0-100之间的随机整数,包头不包尾
                System.out.print(num+",");
            }
            System.out.println();
        }

        ThreadLocalRandom random = ThreadLocalRandom.current();
        int i = random.nextInt(1000, 10000);  //拿1000-10000的随机数,包头不包尾
        
    }
}

4.编码解码类

编码: 加密 看的懂得数据转化成看不懂的数据 (路径,参数,基本信息)

解码: 解密 看不懂的数据转换成看得懂的数据

4.1Base64(1.8之后)

前台数据传输用的比较多

public class Base64Demo {
    private static final String ENCODING = "utf-8";   //加密规则

    public static void main(String[] args) {
        //用户注册 对密码执行加密处理
        userRegister();

        //用户登录,对注册时加密的密码解码处理
        //userLogin();
    }

    private static boolean userLogin() {
        Scanner input = new Scanner(System.in);
        System.out.println("登录用户姓名:");
        String name = input.next();
        System.out.println("登录用户密码:");
        String pass = input.next();

        //登录时,系统会拿注册时的用户名和密码进行比对,假设已拿到
        String regName = "admin";
        String regPass = "MTIzNDU2";

        //获得解码器
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decode = decoder.decode(regPass);
        //字节数组转字符串
        String decodepass = new String(decode,Charset.forName(ENCODING));
        if(!Objects.equals(regName,name) || !Objects.equals(decodepass,pass)){
            return false;
        }
        return true;
    }

    private static void userRegister() {
        Scanner input = new Scanner(System.in);
        System.out.println("请录入用户姓名:");    //admin
        String name = input.next();
        System.out.println("请录入用户密码:");    //123456
        String pass = input.next();

        //密文操作:对原密码加密处理
        //获得编码器
        Base64.Encoder encoder = Base64.getEncoder();
        //开始编码  encodeToString(byte )   需要字符串转字节数组
        pass = encoder.encodeToString(pass.getBytes(Charset.forName(ENCODING )));

        // name—pass
        String info = String.join("-",name,pass);
        System.out.println("用户注册成功,数据已经成功保存 ");
        System.out.println(info);                   //admin-MTIzNDU2

    }
}

4.2信息摘要算法 MessageDigest

抽象类,无子类,用静态方法实现

加密之后是16进制的字符串,该加密不可逆,无法破解。

public class MD5Util {

    private MD5Util(){   //构造私有化
    }
    private static final String[] ARRAY = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
    public static String md5EncodeStr(String sourceStr){

        Objects.requireNonNull(sourceStr);
        StringBuilder builder = new StringBuilder();
        try {
            //1.创建信息摘要的对象
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");   //括号里是加密规则,大小写不区分。检测括号里是否为加密规则,还是随意一个字符串,加一个try...catch...
           //2.更新加密  将源数据提交到加密规则中
            messageDigest.update(sourceStr.getBytes(Charset.forName("utf-8")));
            //3.加密操作
            byte[] bytes = messageDigest.digest();
            //4.字节转字符串
            //System.out.println("加密之后的数据:" + new String(bytes, Charset.forName("utf-8")));
            //将每个字节转换成16进制数据,再拼接成字符串
            //16进制从0-F  一个字节占8个二进制位   一个16进制数字占4个二进制位
            //字节转16进制,一个字节要换成两个16进制内容
            //高低位
            for(byte aByte:bytes){
                 builder.append(byteToHexStr(aByte)); 
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }

    private static String byteToHexStr(byte aByte) {
        int num = aByte;   //先转为整型
        if(num<0){               //aByte是小数,则补码
            num+=256;
        }
        //高位和低位的运算
        int lowIndex = num%16;
        int highIndex = num/16;

        return ARRAY[highIndex]+ARRAY[lowIndex];
    }

    public static void main(String[] args) {
        System.out.println(md5EncodeStr("1234"));
    }

}

public class MD5Util {

    private MD5Util(){   //构造私有化
    }
    private static final String[] ARRAY = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
    public static String md5EncodeStr(String sourceStr){

        Objects.requireNonNull(sourceStr);
        try {
            //1.创建信息摘要的对象
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");   //括号里是加密规则,大小写不区分。检测括号里是否为加密规则,还是随意一个字符串,加一个try...catch...
           //2.更新加密  将源数据提交到加密规则中
            messageDigest.update(sourceStr.getBytes(Charset.forName("utf-8")));
            //3.加密操作
            byte[] bytes = messageDigest.digest();
            //4.字节转字符串
            //System.out.println("加密之后的数据:" + new String(bytes, Charset.forName("utf-8")));
            //将每个字节转换成16进制数据,再拼接成字符串
            //16进制从0-F  一个字节占8个二进制位   一个16进制数字占4个二进制位
            //字节转16进制,一个字节要换成两个16进制内容
            //高低位
            BigInteger bigInteger = new BigInteger(1,bytes);    //调用number的一个子类   1代表将字节数组转成一个正整数
            return bigInteger.toString(16);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(md5EncodeStr("1234"));
    }

}

2.新版

1. Date(相应的格式化类也在其中)

public class DateUtil {

    private DateUtil() {
    }

    //SimpleDateFormat作为全局变量使用,在单线程里面没有任何问题。但在并发里SimpleDateFormat是一个线程不安全的一个类
    //内存:局部的时候 会new很多次  占据很多堆内存
    //线程安全  解决内存过多问题 使用全局进行解决 在单线程没有问题的  在并发里面就会并发安全的问题
    //性能 使用synchronized解决了线程安全以及内存占据过多的问题  但是性能就很低
    //后期使用ThreadLocal,会完美解决
    //现在SimpleDateFormat还是作为局部变量去用吧

    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

    //String 转  Date         dateFormat.parse()
    public static Date strConvertDate(String dateStr) {
        Objects.requireNonNull(dateStr);              //要求不为null
        if (dateStr.isBlank()) {                      //要求不是空字符串
            throw new RuntimeException("字符串数据为空串");
        }
        DateFormat dateFormat = new SimpleDateFormat(PATTERN);
        //转----> 使用日期格式化类转换数据
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();      //字符串时间无法满足pattern模式的要求(字符串时间内容>=pattern)
        }
        return null;
    }

    //Date转String   dateFormat.format()
    public static String dateConvertToStr(Date date) {
        if (date == null) {
            return "";
        }
        Objects.requireNonNull(date);
        DateFormat dateFormat = new SimpleDateFormat(PATTERN);
        return dateFormat.format(date);
    }

}

@Data
public class Employee {

    private Integer id;
    private String name;
    private String phone;
    private Date birthday;
    private Date hireDate;
    private Date createTime;
    private Date updateTime;

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", birthday=" + DateUtil.dateConvertToStr(birthday) +
                ", hireDate=" + DateUtil.dateConvertToStr(hireDate) +
                ", createTime=" + DateUtil.dateConvertToStr(createTime) +
                ", updateTime=" + DateUtil.dateConvertToStr(updateTime) +
                '}';
    }
}

public class DateDemo {
    public static void main(String[] args) {
        //无参构造: 获得当前系统此刻日期时间
        //Date date = new Date();
        //System.out.println(date);

        //registerEmployee();

     /* new Thread(DateDemo::test).start();
      new Thread(DateDemo::test).start();
      new Thread(DateDemo::test).start();
      new Thread(DateDemo::test).start();*/

        test1();
}
    public static void test1() {
        //获得当前时间的毫秒数
        Date date = new Date();
        System.out.println(date.getYear() + 1900);  //从1900年开始算起
        System.out.println(date.getMinutes());
        System.out.println(date.getHours());
        System.out.println(date.getMonth() + 1);    //2
        System.out.println(date.getDate());
        System.out.println(date.getDay());          //1 获得这一天是这一周的第几天
        System.out.println(date.getTime());        //获得时间毫秒数

        //不推荐使用Date里面的getTime获得毫秒数,与对象密切相关
        //推荐
        System.out.println(System.currentTimeMillis());    //毫秒数
        System.out.println(System.nanoTime());     //纳秒数
    }

    public static void test() {

        String[] dateStrArray = {
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00",
                "2020-01-01 12:00:00"};

        //将数组里面所有的字符串都解析成Date类型的数据
        for (String str : dateStrArray) {
            System.out.println(DateUtil.strConvertDate(str));
        }

    }

    //员工入职: 录入员工信息到公司系统里面
    //员工id name age phone 入职时间 生日 新建员工时间  更改员工信息时间  地址
    public static void registerEmployee() {
        Scanner input = new Scanner(System.in);
        Employee employee = new Employee();
        System.out.println("请录入员工name:");
        employee.setName(input.nextLine());

        System.out.println("请录入员工phone:");
        employee.setPhone(input.nextLine());

        //录入的字符串数据如何转换成一个Date类型的数据?
        //String 转 Date

        System.out.println("请录入员工生日:");//2020-01-01 12:00:00
        String birthday = input.nextLine();
        employee.setBirthday(DateUtil.strConvertDate(birthday));

        System.out.println("请录入员工入职时间:");//2020-01-01 12:00:00
        String hireDate = input.nextLine();
        employee.setHireDate(DateUtil.strConvertDate(hireDate));

        //System.out.println("请录入新建员工时间:");
        //获得当前此刻的时间即可
        employee.setCreateTime(new Date());

        //能够获得一个完整的员工信息,用户体验感不高
        //看不懂时间
        //只能看懂: 2020-01-01 12:00:00
        System.out.println("注册员工信息成功,信息如下:" + employee.toString());

        input.close();

    }
}

2. Local....类及相应格式化类

@Data
public class UserInfo {

    private Integer id;
    private String name;
    private String pass;
    private LocalDate birthday;
    private LocalDateTime hireDate;

    private LocalDateTime createTime;

    //local相关的对象转字符串 就调用这个类里面的format
    @Override
    public String toString() {
        return "UserInfo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pass='" + pass + '\'' +
                ", birthday=" + birthday +
                ", createTime=" + createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
                '}';
    }

    //从前到后:  客户端的数据转换后端的对象----> String转Date/localDate  parse
    //从后往前: 给用户看的时候  ----->Date/localDate转String   format
}

public class LocalDemo {

    public static void main(String[] args) {
        //获得当前此刻时间
        //System.out.println(LocalDateTime.now().toString());
        //System.out.println(LocalDate.now());
        //System.out.println(LocalTime.now());
        //System.out.println(Instant.now());  //与中国差8小时   UTC  英国格林尼治时间

        demo3();

    }

    private static void demo3() {

        //1.获得Calendar 类对象 (jdk1.8之前就有了,日历类)
        Calendar calendar = Calendar.getInstance();    //多态  获得系统此刻日历信息
        System.out.println(calendar);

        //获得具体时间单位数据----> get
        //Date date = calendar.getTime();   calendar转换成Date类对象
        System.out.println(calendar.get(Calendar.YEAR));
        //System.out.println(calendar.get(Calendar.MONTH)+1);
        //System.out.println(calendar.get(Calendar.DATE));
        //System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
        //System.out.println(calendar.get(Calendar.HOUR));
        //System.out.println(calendar.get(Calendar.MINUTE));
        //System.out.println(calendar.get(Calendar.SECOND));

        //修改年份值为2021
        //年份-1
        //calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)-1);     //calendar.get(Calendar.YEAR) 拿当前年份
        //calendar.set(Calendar.MONTH,Calendar.MAY);                     //变成5月
       /* calendar.add(Calendar.YEAR,2);      //加两年
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.MONTH)+1);*/

        //calendar.setTime(new Date());    //将指定的date数据转换成Calander对象

        //打印输出指定年份指定月份的完整的日历信息   比如:2022-02
        //calendar.set(Calendar.MONTH,Calendar.MARCH);    //拿2月  (底层的月份从1月到12月,是0-11的序号。拿2月,就得MARCH)
        int maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);     //获得这个月份最大的天数
        System.out.println(maximum);
        //周日  周一
        int day = calendar.get(Calendar.DAY_OF_WEEK);     //获得这一天是这一周的第几天
        System.out.println(day);
    }

    private static void demo2() {

        //1.获得LocalDateTime对象
        //LocalDateTime now = LocalDateTime.now();
       /* System.out.println(now);      //2022-02-28T15:10:06.920312800
        System.out.println(LocalDateTime.now(Clock.systemDefaultZone()));
        System.out.println(LocalDateTime.now(Clock.systemUTC()));
        //所有的时区都使用ZoneId代表
        System.out.println(LocalDateTime.now(Clock.system(ZoneId.of("America/Chicago"))));
        //通过指定的时区获得时间,不太推荐local一些类  本地时间
        System.out.println(ZonedDateTime.now(ZoneId.of("America/Chicago")));*/

        //2020-10-01 12:30:30
        LocalDateTime time = LocalDateTime.of(2022, Month.JANUARY, 1, 12, 30, 30);
        System.out.println(time);

        //TemporalAmount是接口(时间间隔)----->两个实现类: Duration  Period
        // default Temporal plus(TemporalAmount amount) -------plus带一个参数的
        //TemporalUnit是接口(时间单位) 实现类:ChronoUnit
        //public static Duration of(long amount, TemporalUnit unit)    Duration的有参构造

        //time包里的类,值不可变,要想改变,重新创建赋值
        //time = time.plus(Period.ofYears(10));  (用TemporalAmount的Period实现类,Duration不让用)
        //time = time.plus(10, ChronoUnit.YEARS);   //加10年
        //time = time.plusYears(1);
        //time = time.minusMonths(2);     //减2个月

        LocalDateTime now = LocalDateTime.now();
        //获得2个日期间隔的天数   用until();
        //Temporal: 接口 代表日期时间   string是其一个实现类的返回值,故这里可写字符串
        //TemporalUnit: 日期单位
        //public long until(Temporal endExclusive, TemporalUnit unit)
        long durationDays = Math.abs(now.until(time, ChronoUnit.DAYS));   //加绝对值不用考虑正负
        System.out.println(durationDays);

        System.out.println(now.getMonthValue());       //拿月,返回int类型
        System.out.println(now.getMonth());            //拿月,返回Month枚举类
        System.out.println(now.getDayOfWeek());        //这一周的第几天(欧美是周日为一周的第一天)
        System.out.println(now.getDayOfMonth());
    }

    private static void demo1() {
        Scanner input = new Scanner(System.in);
        UserInfo userInfo = new UserInfo();
        System.out.println("请录入用户name:");
        userInfo.setName(input.nextLine());

        //String转LocalDate
        //字符串转jdk1.8+ time包里面的任意一个类  就使用这个类里面parse方法

        System.out.println("请录入用户生日:");
        String birthday = input.nextLine();
        userInfo.setBirthday(LocalDate.parse(birthday));
        System.out.println(userInfo.getBirthday());

        //转:
        System.out.println("请录入用户入职时间:");
        String hireDate = input.nextLine();
        userInfo.setHireDate(LocalDateTime.parse(hireDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        //现在:now
        userInfo.setCreateTime(LocalDateTime.now());//获得的是当前此刻时间

        System.out.println(userInfo.toString());
    }
}

3. NumberFormat

public class NumberFormatDemo {

    public static void main(String[] args) {
        demo3();
        
    }

    private static void demo3() {
        
        //3.对钱数值进行格式化    (金钱的整数部分,每三位一个逗号)
        double money = 16637743645556364353534535.6787346;
        System.out.println(money);
        NumberFormat numberFormat = new DecimalFormat(",###.###");
        System.out.println(numberFormat.format(money));

        //存储用户余额: 
        // 法一:将钱全部转成分,再用long类型存
        //法二:分成2部分(用小数点分),分别用long或double存,再拼接
        
        //在开发中,余额使用什么类型维护?  BigDecimal---->小数运算(不丢失任意精度)
        //System.out.println(0.1+0.2);
        //System.out.println(0.3/0.1);    2.9999999 会丢失精度

        BigDecimal num1 = new BigDecimal("0.3");
        BigDecimal num2 = new BigDecimal("0.1");
        System.out.println(num1.divide(num2));      //不会丢失精度   divide除

        BigDecimal num3 = BigDecimal.valueOf(0.2);
        System.out.println(num3.add(num2));    //add加
        
    }

    private static void demo2() {
        
        //2. 将数据转换成百分制的数字 小数点之后保留3个数字
        double num = 0.1234567;
        NumberFormat numberFormat = new DecimalFormat(".###%");
        String result = numberFormat.format(num);
        System.out.println(result);
    }

    private static void demo1() {
        
        //1. 保留小数点后面指定的位数
        double num = 1100.567895;
        //格式化数字类  NumberFormat
        //NumberFormat numberFormat = new DecimalFormat("0000000.000");
        NumberFormat numberFormat = new DecimalFormat("######.###");
        String result = numberFormat.format(num);
        System.out.println(result);

        //String转Double        Double.parseDouble();
        System.out.println(Double.parseDouble(result));
    }
}

4. Random

public class RandomDemo {

    public static void main(String[] args) {

        //System.out.println(Math.random());//0.0-1.0   这个是Manth类里

        demo1();
    }

    private static void demo1() {
        //用random的子类ThreadLocalRandom,更好用,两者都线程安全,但并发里,ThreadLocalRandom性能更好
        ThreadLocalRandom random = ThreadLocalRandom.current();
        int num = random.nextInt(1000, 10000);    //1000-10000,方法也比Random好用
    }

    private static void demo() {
        
        //循环5次 在每次循环里面获得5个随机数字  1000-10000
        //预测到随机数是多少? 可以预测 指定seed
        //如下为伪随机
        for (int i = 1; i <= 5; i++) {
            Random random = new Random(1000);   //若将其拿出循环,和Random()不带参一样无法预测
            for (int j = 1; j <= 5; j++) {
                //获得随机数
                int randomNum = (random.nextInt(9000) + 1000);   //1000-10000
                System.out.print(randomNum + "\t");
            }
            System.out.println();
        }
    }
}

5. Base64和MD5

public class PassDemo {

    public static void main(String[] args) {
        
        System.out.println(MD5Util.md5("1234"));
    }

    private static void md5() {
        String pass = "1234";
        try {
            //1.获得信息摘要对象
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            //2.更新摘要算法---->将要加密的文本数据传输到算法中
            pass = pass + SALT;    //加盐,MD5不可逆,加盐是有效的
            messageDigest.update(pass.getBytes());
            //3.执行加密操作
            byte[] bytes = messageDigest.digest();
            //将字节数组里面的每个字节数据转换成对应的16进制的字符
            //一个字节数据可以转成几个16进制内字符数据?  一个字节8bit,一个16进制的字符4bit
            //一个字节----> 转换成2个16进制的字符
            //字节数组里的每个字节数据转成对应的16进制的字符 手写如下:
           /* StringBuilder builder = new StringBuilder();
            for (byte aByte : bytes) {
                int num = aByte;
                if (num < 0) {
                    num += 256;
                }
                int low = num / 16;
                int high = num % 16;
                builder.append(array[low]).append(array[high]);
            }
            System.out.println(builder);*/
            //法二:BigInteger
            String s = new BigInteger(1, bytes).toString(16);   //1标识为正,不懂看底层
            System.out.println(s);
            //81dc9bdb52d04dc20036dbd8313ed055
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    //16进制里面字符数据是固定  0-F
    //0-15
    static char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    
    //登录: 将登录时密码也加密,与注册时加密的密码进行比较(现实中多用此方法)
    //或者将注册时的密码解密,与登录时的密码比较
    private static void demo2() {
        String pass = "MTIzNHpoYW5nc2FuJSQjQCE=";
        //1.获得Base64解码器
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] bytes = decoder.decode(pass);
        //字节数组转String
        String s = new String(bytes);
        System.out.println(s);
    }

    
    //Base64是完全可逆的。(可以破解)
    //加盐,为避免破解,提高安全性的一种操作。只针对不可逆的加密算法,对Base64无效,下面流程只是感受下
    private static final String SALT = "zhangsan%$#@!";
    //模拟注册
    private static void demo1() {
        String pass = "1234";        //密码
        pass = pass + SALT;          //加盐
        //Base64(使用一些字母和数字和特殊符号组成)
        //编码/加密----> 编码器
        //1.获得编码器
        Base64.Encoder encoder = Base64.getEncoder();
        //2.对文本数据进行加密处理
        //将字符串转换成字节数组
        String encodePass = encoder.encodeToString(pass.getBytes());
        System.out.println(encodePass);    //MTIzNA==
    }
}

public class MD5Util {

    private MD5Util() {
    }

    public static String md5(String sourceStr) {

        Objects.requireNonNull(sourceStr);
        StringBuilder builder = new StringBuilder();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");   //获得信息摘要对象
            messageDigest.update(sourceStr.getBytes());     //更新摘要算法,要加密的文件数据传到算法中
            byte[] bytes = messageDigest.digest();     //加密
            for (byte aByte : bytes) {
                builder.append(byteToHex(aByte));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return builder.toString().toUpperCase();
    }

    private static final char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static String byteToHex(byte aByte) {      //字节数组里的每个字节数据转成对应的16进制的字符
        int num = aByte;
        if (num < 0) {
            num += 256;
        }
        int low = num / 16;
        int high = num % 16;
        return array[low] + "" + array[high];
    }
}

6.课后作业

1.旧版

1.将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss

public class Exercise1 {
    public static void main(String[] args) {
     demo1();  //(jdk1.8之前)
     demo2();  //(jdk1.8之后)
    }

    private static void demo2() {
        LocalDateTime localDateTime = LocalDateTime.of(2022,Calendar.FEBRUARY,1,12,0,0);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN);
        String format = formatter.format(localDateTime);
        System.out.println(format);

        //String format1 = localDateTime.format(formatter);

    }

    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

    private static void demo1() {
       //Date转String
        //1.创建Date对象
        Date date = new Date();  //获得系统当前时间
        long time = date.getTime();  //获得毫秒数(不推荐)

        long millis = System.currentTimeMillis();  //推荐

        //创建Calender对象
        Calendar calendar = Calendar.getInstance();
        calendar.set(2022,Calendar.FEBRUARY,1,12,0,0);  //2022-2-1 12:00:00

        //Calender转Date
        Date date1 = calendar.getTime();

        //2.创建格式类DateFormat
        DateFormat dateFormat = new SimpleDateFormat(PATTERN);
        String dateStr = dateFormat.format(date);
        System.out.println(dateStr);
    }
}

2.使用Calendar类的相关属性以及方法!打印出某年某个月的日历信息!(要求年月日由命令行输入)

public class Exercise2 {
    public static void main(String[] args) {
        //demo3();
        demo4();
    }

    private static void demo4() {
        //动态月份的情况
        int year = 2022;
        Scanner input = new Scanner(System.in);
        System.out.println("请录入月份:");
        int month = input.nextInt();

        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,1);

        System.out.println("日\t一\t二\t三\t四\t五\t六");
        int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        //判断1号有几个空格
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        for (int i = 1; i < day; i++) {
            System.out.print("\t");
        }

        for (int i = 1; i <= totalDay; i++) {
            System.out.print(i+"\t");
            //判断当前天是否为一周最后一天,是则换行
            calendar.set(Calendar.DAY_OF_MONTH,i);
            if (calendar.get(Calendar.DAY_OF_WEEK)==7){
                System.out.println();
            }
        }

    }

    private static void demo3() {
        //固定月份的情况
        int year = 2022;
        int month = 2;

        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,1);     //2月份的序号是1

        System.out.println("日\t一\t二\t三\t四\t五\t六");
        int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        System.out.print("\t\t");
        for (int i = 1; i <= totalDay; i++) {
            System.out.print(i+"\t");
            //判断当前天是否为一周最后一天,是则换行
            calendar.set(Calendar.DAY_OF_MONTH,i);
            if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY){
                System.out.println();
            }
        }

    }
}

3.计算两个时间相差几个小时

public class Exercise4 {
    public static void main(String[] args) {
        //demo1();
        demo2();
    }

    private static void demo2() {
        //LocalDateTime 与 LocalDateTime
        LocalDateTime dateTime1 = LocalDateTime.of(2022,Calendar.FEBRUARY,1,12,0,0);
        LocalDateTime dateTime2 = LocalDateTime.now();

        long hours = dateTime1.until(dateTime2, ChronoUnit.HOURS);  //括号里的减括号外面的
        System.out.println(hours);
    }

    private static void demo1() {
        //Date 与 Date
        Calendar calendar = Calendar.getInstance();
        calendar.set(2022,Calendar.FEBRUARY,1,12,0,0);  //2022-2-1 12:00:00
        Date date1 = calendar.getTime();
        Date date2 = new Date();

        long result = Math.abs((date1.getTime()-date2.getTime())/1000/3600);
        System.out.println(result);
    }
}

4.一个方法,要求传入时间和间隔天数,返回新的日期

public class Exercise5 {
    public static void main(String[] args) {
        demo1(new Date(),10);   //Date之间的操作
        demo2(LocalDate.now(),10);   //LocalDate之间的操作
    }

    private static LocalDate demo2(LocalDate localDate,int days) {
        return localDate.plusDays(days);

    }

    private static Date demo1(Date date,int days) {
         //传入时间加时间间隔
         //用毫秒数来写
        long time = date.getTime() + Duration.ofDays(days).toMillis();   //加号后面的是天转毫秒

        return new Date(time);
    }
}

5.要求写一个工具类,可以自定义获取N个随机数字或字母(0~9,a~z,A~Z混合一起)

public class Exercise6 {
    public static void main(String[] args) {
        demo1();
        //demo2();
    }

    private static void demo2() {
        StringBuilder builder = new StringBuilder();

        ThreadLocalRandom random = ThreadLocalRandom.current();
        int choice = random.nextInt(0,3);
        for (int i = 1; i <= 5; i++) {
            char ch = ' ';
            switch (choice) {
                case 0:
                    ch = (char)random.nextInt(48,57);
                    break;
                case 1:
                    ch = (char)random.nextInt(68,90);
                    break;
                case 2:
                    ch = (char)random.nextInt(97,122);
                    break;
            }
            builder.append(ch);
        }
        System.out.println(builder.toString());
    }

    private static void demo1() {
        //48-57 0-9      A-Z 65-90     a-z 97-122
        ThreadLocalRandom random = ThreadLocalRandom.current();

        StringBuilder builder = new StringBuilder();
        int count = 5;
        for(int i=1;i<=count;i++){
            int num = random.nextInt(48,122);
            if(num>=48 && num<=57){
                num = num -48;     //直接变成对应数字
                builder.append(num);
            }else if( (num>=65 && num<=90) || (num>=97 && num<=122) ){
                char ch = (char)num;    //数字转字符
                builder.append(ch);
            }else {
                i--;
            }
        }
        System.out.println(builder.toString());
    }
}

2.新版

public class ExerciseDemo {

    public static void main(String[] args) {
        //System.out.println(demo5(new Date(), 10));
        demo6();
    }

private static void demo6() {
        //6. 要求写一个工具类,可以自定义获取N个随机数字或字母(0~9,a~z,A~Z混合一起)
        StringBuilder code = new StringBuilder();
        ThreadLocalRandom random = ThreadLocalRandom.current();
        //ASCII
        //0~9   48-57
        //A~Z   65-90
        //a~z   97-122
        for (int i = 0; i < 6; i++) {
            int num = random.nextInt(48, 123);
            if ((num > 57 && num < 65) || (num > 90 && num < 97)) {
                i--;
                continue;
            }
            code.append((char) num);
        }

        System.out.println("验证码:" + code);

    }

private static Date demo5(Date date, int day) {

        //LocalDate的使用场景
        //1. 修饰属性
        //2. 每天创建新的目录 以当前时间为目录名称    String string = LocalDate.now().toString();

        LocalDate localDate = LocalDate.now();
        localDate = localDate.plusDays(10);
        System.out.println(localDate);

        //5. 一个方法,要求传入时间和间隔天数,返回新的日期
        //将day的数据运算到date时间当
        //date+day
        /*long time1 = date.getTime();
        long millis = Duration.ofDays(day).toMillis();
        date.setTime(time1 + millis);*/

        //使用Calendar
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);

        return calendar.getTime();
    }

private static void demo4() {
        LocalDate localDate1 = LocalDate.now();//3-1
        LocalDate localDate2 = LocalDate.of(2021, Month.MARCH, 2);//3-2
        long days = Math.abs(localDate1.until(localDate2, ChronoUnit.DAYS));

        System.out.println(Duration.ofDays(days).toHours());

        /*Period period = localDate2.until(localDate1);
        System.out.println(period.toString());
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());*/

    }

  private static void demo3() {

        //3. 从命令行输入一个字符串!要求从中随机选择6个字符组成验证码
        String str = "ehret76235423lldshge723656325gfds";
        //随机获得6个字符
        //Random---->ThreadLocalRandom
        ThreadLocalRandom random = ThreadLocalRandom.current();

        //获得字符串里面的一个字符数据  char charAt(int index);
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            //随机是字符的索引值  index>=0 index<length()
            code.append(str.charAt(random.nextInt(str.length()))); //random.nextInt(str.length())包头不包尾
        }
        System.out.println(code.toString());

        //一般验证码: 纯数字  数字+字母
        //0-9 a-z
       /* System.out.println(UUID.randomUUID().toString());
        System.out.println(UUID.randomUUID().toString());
        System.out.println(UUID.randomUUID().toString());
        System.out.println(UUID.randomUUID().toString());*/

        //推荐   UUID类(在java.util包里),生成一个128位无符号的唯一的字符串数据,16进制的
        System.out.println(UUID.randomUUID().toString().substring(0, 6));  //一般拿验证码也可以截取其字符串前六位
        //纯数字   System.currentTimeMillis()是一个毫秒数,返long类型
        System.out.println(String.valueOf(System.currentTimeMillis()).substring(0, 6));
    }

    private static void demo2() {

        //2. 使用Calendar类的相关属性以及方法!打印出某年某个月的日历信息!(要求年月日由命令行输入)
        int year = 2022;
        int month = Calendar.MARCH;

        //Calendar类里面常用的功能方法
        //1.Calendar getInstance();  获得Calender类对象
        //2.long get(int field);     拿年/月/日
        //3. void set(int field,int newValue);  修改年份
        //4. void add(int field,int duration);  增加年份

        Calendar calendar = Calendar.getInstance();
       /* calendar.set(Calendar.YEAR,year);
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH,1);*/
        calendar.set(year, month, 1);

        System.out.println("日\t1\t2\t3\t4\t5\t6");
        //1.1 获得指定月份的总天数
        int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        //1.2 获得指定月份1号属于这一周的第几天
        int num = calendar.get(Calendar.DAY_OF_WEEK);
        for (int i = 1; i < num; i++) {
            System.out.print("\t");
        }

        for (int day = 1; day <= totalDay; day++) {
            //一周就7天  换行  判断一下这一天是否是这一周的最后一天
            System.out.print(day + "\t");
            calendar.set(Calendar.DATE, day);
            if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
                System.out.println();
            }
        }
    }

 private static void demo1() {

        //1.将Date转换成String
        //1.1 创建pattern
        StringBuilder pattern = new StringBuilder("yyyy-MM-dd HH:mm:ss a E");
        //1.2 创建Date对象
        //Date类常用构造方法:  new  Date()     new Date(long time) (这里是毫秒数)
        Date date = new Date();
        //1.3 创建格式化日期对象
        //Format--->
        // DateFormat---->SimpleDateFormat
        // NumberFormat---->DecimalFormat
        DateFormat dateFormat = new SimpleDateFormat(pattern.toString());
        //1.4 转换
        String result = dateFormat.format(date);
        System.out.println(result);

        //2.LocalDateTime转换成String
        //2.1 创建LocalDateTime对象
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);//2022-03-01T09:44:17.159568100

        System.out.println(now.format(DateTimeFormatter.ofPattern(pattern.toString())));
    }
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值