Java笔记_11(常用API)

一、常用的API

1.1、Math

  • 是一个帮助我们进行数学计算的工具类
  • 私有化构造方法,所有的方法都是静态的

Math类的常用方法

方法名说明
public static int abs(int a)获取参数绝对值
public static doublie ceil(double a)向上取整
public static doublie floor(double a)向下取整
public static int round(float a)四舍五入
public static int max(int a,int b)获取两个int值中的较大值
public static doublie pow(double a,double b)返回a的b次幂的值
public static doublie random()返回为double的随机值,范围[0.0,1.0)
public static doublie sqrt(double a)返回平方根
public static doublie cbrt(double a)返回立方根

Math练习

  • 判断是否为质数
public static boolean isProme(int a){

        for (int i = 1; i <Math.sqrt(a) ; i++) {
            if(a%i==0){
                return false;
            }
        }
        return true;
    }
  • 获取四叶玫瑰数
int count = 0;
        for (int i = 1000; i < 9999; i++) {
            int ge = i%10;
            int shi = i/10%10;
            int bai = i/100%10;
            int qian = i/1000%10;

            double sum = Math.pow(ge,4)+Math.pow(shi,4)+Math.pow(bai,4)+Math.pow(qian,4);

            if(sum==i){
                count++;
                System.out.println(i);
            }
        }
        System.out.println(count);

1.2、System

  • System也是工具类,提供一些与系统相关的方法

计算机中的时间原点

1970年1月1日 08:00:00
我国在东八区,有八小时的时差

原因:
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会。开始着手创造一个全新的革命性的操作系统。他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNIX。

1970年1月1日 算C语言的生日

  • 1秒 = 1000毫秒
  • 1毫秒 = 1000微秒
  • 1微秒 = 1000纳秒
方法名说明
public static void exit(int status)终止当前运行的Java虚拟机
public static long currentTimeMillis()返回当前系统的时间毫秒值形式
public static void arraycopy(数据源数组,起始索引,目的地索引,起始索引,拷贝个数)数组拷贝

使用arraycopy时注意事项:

  1. 如果数据源数组和目的地数组两者都是基本数据类型,两者的数据类型必须保持一致,否则会进行报错
  2. 在拷贝的时候需要考虑数组的长度,如果超出范围也会报错
  3. 如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型

1.3、Runtime

  • Runtime表示当前虚拟机的运行环境
方法名说明
public static Runtime getRuntime()当前系统的运营环境对象
public void exit(int status)停止虚拟机
public int availableProcessors()获得CPU的线程数
public long maxMemory()JVM能从系统中获取总内存大小(单位byte)
public long totalMemory()JVM已经从系统中获取总内存大小(单位byte)
public long freeMemory()JVM剩余内存大小(单位byte)
public Process exec(String command)运行cmd命令

exec命令关机 shutdown(加上参数才能执行)

  1. -s :默认在1分钟之后关机
  2. -s -t 指定时间:指定关机时间
  3. -a :取消关机操作
  4. -r :关机并重启

1.4、Object

  • Object是Java中的顶级父类。所有的类都直接或间接的继承于Object类。
  • Object类中的方法可以被所有子类访问,所以我们要学习Object类和其中的方法
方法名说明
public String toString()返回对象的字符串表示形式
public boolean equals(object obj)比较两个对象是否相等
protected object clone(int a)对象克隆

println():方法

  • 参数:表示打印的对象
  • 核心逻辑:当我们打印一个对象的时候,底层会调用对象的toString方法,把对象变成字符串。然后再打印在控制台上,打印完毕换行处理。

toString方法结论:

  1. 如果我们打印一个对象,想要看到属性值的话,那么就重写tostring方法就可以了。
  2. 在重写的方法中,把对象的属性值进行拼接。

equals方法结论:

  1. 如果没有重写equals方法,那么默认使用object中的方法进行比较,比较的是地址值是否相等
  2. 一般来讲地址值对于我们意义不大,所以我们会重写,重写之后比较的就是对象内部的属性值了。

String中的equals方法

  • 先判断参数是否为字符串如果是字符串,再比较内部的属性
  • 但是如果参数不是字符串,直接返回false

StringBulider中的equals方法

  • 在StringBuilder当中,没有重写equals方法使用的是object中的在Object当中默认是使用==号比较两个对象的地址值

1.5、浅克隆、深克隆

  • 把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制

细节:

方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去

书写细节:

  1. 重写Object中的clone方法
  2. 让javabean类实现Cloneable接口
  3. 创建原对象并调用clone就可以了。

Cloneable

  • 如果一个接口里面没有抽象方法表示当前接口是一个标志性接口,现在Cloneable表示一旦实现了,那么当前类的对象就可以被克隆
  • 浅克隆
    在这里插入图片描述
    Object中的克隆是浅克隆
    重写的代码块
protected Object clone() throws CloneNotSupportedException{
        //调用父类中的clone方法
        //相当于让java帮我们克隆一个对象,并把克隆之后的对象返回
        return super clone();
    }
  • 深克隆

在这里插入图片描述
重写的clone()方法

protected Object clone() throws CloneNotSupportedException{
        //调用父类中的clone方法
        //相当于让java帮我们克隆一个对象,并把克隆之后的对象返回
        int[] data = this.data;
        int[] data2 = new int[data.length];

        for (int i = 0; i < data.length; i++) {
            data2[i] = data[i];
        }
        User u =(User) super.clone();
        u.data = data2;
        return u;
    }

1.6、对象工具类的Objects

方法名说明
public static boolean equals(Object a,Object b)先做非空判断,比较两个对象
public static boolean isNull(Object obj)判断对象是否为null,为null返回true,反之
public static boolean nonNull(Object obj)判断对象是否为null,跟isNull的结果相反

细节:

  1. 方法的底层会判断 第一个对象 是否为null,如果为null,直接返回false
  2. 如果 第一个对象 不为null,那么就利用 第一个对象 再次调用equals方法
  3. 此时 第一个对象设置的对象 类型,所以最终还是会调用 设置的对象 中的equals方法。
  4. 如果没有重写,比较地址值,如果重写了,就比较属性值。

1.7、BigInteger(大整数)

BigInteger构造方法

方法名说明
public BigInteger(int num,Random rnd)获取随机大的整数,范围:[0~2的num次方-1]
public BigInteger(String val)获取指定的大整数(字符串中必须是整数,否则会报错)
public BigInteger(String val,int radix)获取指定进制的大整数(字符串中的数字必须与进制吻合)
public static BigInteger valueOf(long val)静态方法获取BigInteger的对象,内部有优化
  • 对象一旦创建,内部记录的值不能发生改变
  • valueOf(long val)方法中会对 -16~16 之间的值进行优化,会创建好这些数字的对象,当赋值在这个范围内使用==号对比两个对象得到的是true

BigInteger常见成员方法

方法说明
public BigInteger add(BigInteger val)加法
public BigInteger subtract(BigInteger val)减法
public BigInteger multiply(BigInteger val)乘法
public BigInteger divide(BigInteger val)除法,获取商
public BigInteger[ ] divideAndRemainder(BigInteger val)除法,获取商和余数(数组0索引是商,1索引是余数)
public boolean equals(Object x)比较是否相同
public BigInteger pow(int exponent)次幂
public BigInteger max/min(BigInteger val)返回较大值/较小值
public int intValue(BigInteger val)转为int类型整数,超出范围数据有误

1.8、BigDecimal(大小数)

BigDecimal的作用

  • 用于小数的精确计算
  • 用来表示很大的小数

BigDecimal的构造方法

方法说明
public BigDecimal( double val)通过double来获得一个小数 (得到的小数有可能不精确)
public BigDecimal( String val)通过String获得一个小数
public static BigDecimal valueOf( double val)静态方法创建一个对象

细节:

  1. 如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法
  2. 如果要表示的数字比较大,超出了double的取值范围,建议使用构造方法
  3. 如果我们传递的是0~10之间的整数,包含0,包含10,那么方法会返回已经创建好的对象,不会重新new

BigDecimal的使用

方法名说明
public static BigDecimal valueof(double val)获取对
public BigDecimal add(BigDecimal val)加法
public BigDecimal subtract(BigDecimal val)减法
public BigDecimal multiply(BigDecimal val)乘法
public BigDecimal divide(BigDecimal val)除法
public BigDecimal divide(BigDecimal val,精确几位,舍入模式)除法

舍入模式(举例):

  • UP:远离零方向舍入的舍入模式
  • DOWN:向零方向舍入的舍入模式
  • CEILING:向正无限大方向舍入的舍入模式
  • FLOOR:向负无限大方向舍入的舍入模式
  • HALF_UP:小数距离两个数之间距离相等时向上舍入
  • HALF_DOWN:小数距离两个数之间距离相等时向下舍入

二、正则表达式

2.1、正则表达式基础知识

正则表达式的作用:

  1. 校验字符串是否满足规则
  2. 在一段文本中查找满足要求的内容

字符类(只能匹配一个字符)

字符作用
[abc]只能是a, b,或c
[^abc]除了a, b, c之外的任何字符
[a-zA-Z]a到zA到Z,包括(范围)
[a-d[m-p]]a到d,或m到p
a-z&&[def]a-z和def的交集。为: d, e, f
[a-z&&[^bc]]a-z和非bc的交集。(等同于[ad-z])
[a-z&&[^m-p]]a到z和除了m到p的交集。(等同于[a-lq-z])

细节:
如果要求两个范围的交集,那么需要写符号&&
如果写成了一个&,那么此时&表示就不是交集了,而是一个简简单单的&符号(没有任何含义)

预定义字符(只匹配一个字符)

字符作用
.任何字符
\d一个数字:[0-9]
\D非数字:[^0-9]
\s一个空白字符:[ \t\n\x0B\f\r]
\S非空白字符:[^\s]
\w[a-zA-Z_0-9]英文、数字、下划线
\W[^\w]一个非单词字符

\在Java中是转义字符
\\表示前面的\是一个转义字符,改变了后面\原本的含义,把他变成了一个普普通通的\

数量词

字符作用
X?X,一次或0次
X*X,零次或多次
X+X,一次或多次
x{n}X,正好n次
X{n,}X,至少n次
X{n,m}X,至少n但不超过m次

2.2、正则表达式-练习1

在这里插入图片描述

package API_.RegexDome;

public class Test1 {
    public static void main(String[] args) {
        //验证手机号码  13112345678 17665063261 13112345678
        String regex1 = "1\\d{10}";

        System.out.println("13112345678".matches(regex1));
        System.out.println("17665063261".matches(regex1));
        System.out.println("13112345678".matches(regex1));
        System.out.println("131123456782".matches(regex1));

        System.out.println("-------------------------------------------------");
        //验证座机电话号码 020-2324242 02122442 027-42424 0712-3242434

        String regex2 = "0\\d{2,3}-?[1-9]\\d{4,9}";
        System.out.println("020-2324242".matches(regex2));
        System.out.println("02122442".matches(regex2));
        System.out.println("027-42424".matches(regex2));
        System.out.println("0712-3242434".matches(regex2));

        System.out.println("-------------------------------------------------");
        //验证邮箱号码 3232323@qq.com   zhangsan@itcast.cnn   dlied0009@163.com   dle13121@pci.com.cn

        String regex3 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}";
        System.out.println("3232323@qq.com".matches(regex3));
        System.out.println("zhangsan@itcast.cnn".matches(regex3));
        System.out.println("dlied0009@163.com".matches(regex3));
        System.out.println("dle13121@pci.com.cn".matches(regex3));

    }
}

2.3、正则表达式-练习2

在这里插入图片描述

  • (?i)可以忽略后面字母的大小写
  • 编写正则的小心得
    1. 按照正确的数据进行拆分
    2. 找每一部分的规律,并编写正则表达式
    3. 把每一部分的正则拼接在一起,就是最终的结果
    4. 书写的时候:从左到右去书写。
package API_.RegexDome;

public class Test2 {
    public static void main(String[] args) {
        //用户名要求
        String regex1 = "\\w{4,16}";

        System.out.println("zhangsan_123".matches(regex1));
        System.out.println("--------------------------------------------");

        //身份证号码验证
        String regex2 = "[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]";

        System.out.println("411423200006012222".matches(regex2));
    }
}

2.4、爬虫

Pattern类:表示正则表达式
Matcher类:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取。

package API_.RegexDome;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test3 {
    public static void main(String[] args) {
        String str = "Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11," +
                "因为这两个是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会逐渐登上历史舞台";
        //获取正则表达式对象
        Pattern p = Pattern.compile("Java\\d{0,2}");
        //获取文本匹配器对象
        //m:文本匹配器对象
        //str:大串
        //p:规则
        //m要在str中找到符合p规则的小串
        Matcher m = p.matcher(str);

        //拿着文本匹配器从头开始读取,寻找是否有满足规则的字串
        //如果没有,方法返回false
        //如果有,返回true,在底层记录字串的其实索引和结束索引+1
        boolean b = m.find();
        //方法底层会根据find方法记录的索引进行字符串的截取
        // subString(起始索引,结束索引);包头不包尾
        //(0,4)但是不包含4索引
        String s1 = m.group();
        System.out.println(s1);

    }
}

2.5、带条件爬取、贪婪爬取和识别正则的两个方法

  • 定义正则表达式
    • ?理解为前面的数据
    • =表示在Java后面要跟随的数据
    • :表示获取的是所有的与之类型相关的字符
    • !表示获取去除带有后面跟随数据的相关字符串
    • 获取的数据是括号之前的
package API_.RegexDome;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test4 {
    public static void main(String[] args) {
        /*需求1:爬取版本号为8,11,17的Java文本,但是只要java,不显示版本号。
        需求2:爬取版本号为8,11,17的Java文本。正确爬取结果为: Java8 Java11 Java17 Java17
        需求3:爬取除了版本号为8,11,17的Java文本,

        */

        String s = "java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和JAva11," +
                "因为这两个是长期支持版本,下一个长期支持版本是JAVa17,相信在未来不久JAVA17也会逐渐登上历史舞台";

        //需求一:
        String regex1 = "((?i)java)(?=8|11|17)";//(?i)忽略大小写
        //需求二:
        String regex2 = "((?i)java)(8|11|17)";
        String regex3 = "((?i)java)(?:8|11|17)";

        Pattern p =Pattern.compile(regex3);
        Matcher m = p.matcher(s);

        while (m.find()){
            System.out.println(m.group());
        }

        
    }
}

贪婪爬取:尽可能地多获取数据
非贪婪爬取:尽可能地少获取数据

  • Java中,默认的就是贪婪爬取
  • 在定义的正则中有出现+时在其后面加上?即可使其变为非贪婪爬取

正则表达式在字符串方法中的使用

方法名说明
public String[ ] matches (String regex)判断字符串是否满足正则表达式的规则
public String replaceAll(String regex, String newStr)按照正则表达式的规则进行替换
public String[ ] split(String regex)按照正则表达式的规则切割字符串
package API_.RegexDome;

public class Test5 {
    public static void main(String[] args) {
        String s = "例阿斯顿asdasdasda啊实打实的asdadas";

        String result = s.replaceAll("[\\w&&[^_]]+","vs");

        System.out.println(result);

        String[] arr  = s.split("[\\w&&[^_]]+");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

2.6、捕获分组和非捕获分组

  • 分组就是一个小括号
    • 每一组都是有组号的,也就是序号
    • 规则1:从1开始,连续不间断
    • 规则2:以左括号为基准,最左边的是第一组,其次是第二组,以此类推
    • \\组号将某一组的数据拿出来再用一次
package API_.RegexDome;

public class Test6 {
    public static void main(String[] args) {
        //需求1:判断一个字符串的开始字符和结束字符是否一致?只考虑一个字符
        // 举例:a123a  b456b  17891  &abc&  a123b(false)
        String regex1 = "(.).+\\1";
        System.out.println("a123a".matches(regex1));
        System.out.println("b456b".matches(regex1));
        System.out.println("17891".matches(regex1));
        System.out.println("&abc&".matches(regex1));
        System.out.println("a123a".matches(regex1));
        System.out.println("a123b".matches(regex1));
        System.out.println("-------------------------------------------------");

        //需求2:判断一个字符串的开始部分和结束部分是否一致?可以有多个字符
        //举例:abc123abc  b456b   123789123  &!@abc&!@  abc123abd(false)
        String regex2 = "(.+).+\\1";
        System.out.println("abc123abc".matches(regex2));
        System.out.println("b456b".matches(regex2));
        System.out.println("123789123".matches(regex2));
        System.out.println("&!@abc&!@".matches(regex2));
        System.out.println("abc123abd".matches(regex2));
        System.out.println("-------------------------------------------------");

        //需求3:判断一个字符串的开始部分和结束部分是否一致?开始部分内部每个字符也需要一致
        //举例: aaa123aaa  bbb456bbb  111789111  &&abc&&
        
       	//(.):把首字母看作一组
        // \\2:把首字母拿出来再次使用
        String regex3 = "((.)\\2*)\\w+\\1";
        System.out.println("aaa123aaa".matches(regex3));
        System.out.println("bbb456bbb".matches(regex3));
        System.out.println("111789111".matches(regex3));
        System.out.println("&&abc&&".matches(regex3));
        System.out.println("-------------------------------------------------");
    }
}

  • 捕获分组:
    • \\组号——在正则内部捕获
    • $组号——在正则外部捕获
package API_.RegexDome;

public class Test7 {
    public static void main(String[] args) {
        String s = "我我我我我我我要要要要要要学学学学学学编编编编编编编编程程程程程";

        String result = s.replaceAll("(.)\\1+","$1");
        System.out.println(result);

    }
}

非捕获分组

符号含义举例
(?:正则)获取所有Java(?:8|11|17)
(?=正则)获取前面部分Java(?=8|11|17)
(?!正则)获取不是指定内容的前面部分Java(?!8|11|17)
  • 分组之后不需要再用本组数据,仅仅把数据括起来,不占组号

三、JDK7时间

3.1、JDK7时间-Date

世界标准时间

格林尼治时间/格林威治时间(Greenwich Mean Time)简称GMT。
目前世界标准时间((UTC)已经替换为:原子钟

中国标准时间

世界标准时间+8小时

时间换算单位

1秒 = 1000毫秒
1毫秒 = 1000微秒
1微秒 = 1000纳秒

Date时间类
Date类是一个JDK写好的Javabean类,用来描述时间,精确到毫秒。
利用空参构造创建的对象,默认表示系统当前时间。
利用有参构造创建的对象,表示指定的时间。

  1. 如何创建日期对象?

    • Date date = new Date();
    • Date date = new Date(指定毫秒值);
  2. 如何修改时间对象的毫秒值?

    • setTime(毫秒值)
  3. 如何获取时间对象中的毫秒值

    • getTime();
package API_.JDK7DateDome;

import java.util.Date;
import java.util.Random;

public class Dome1 {
    public static void main(String[] args) {
        //创建一个表示时间原点的对象
        Date d1 = new Date(0L);
        //获取d1时间的毫秒值
        long time  = d1.getTime();
        //在这个基础上我们要加一年的毫秒值即可
        time = time + 1000L*60*60*24*365;
        //把这个时间设置到d1里面
        d1.setTime(time);
        //打印出来
        System.out.println(d1);


        Random r = new Random();
        Date d2 = new Date(Math.abs(r.nextInt()));
        Date d3 = new Date(Math.abs(r.nextInt()));

        long date2 = d2.getTime();
        long date3 = d3.getTime();

        if (date3>date2){
            System.out.println("后者大于前者");
        } else if (date3<date2) {
                System.out.println("前者大于后者");
        }else {
            System.out.println("两者一样");
        }

    }
}

3.2、JDK7时间-SimpleDateFormat类

  • 格式化:把时间变成我们喜欢的格式
  • 解析:把字符串表示的时间变成Date对象

构造方法:

构造方法说明
public SimpleDateFormat()构造一个SimpleDateFormat,使用默认格式
public simpleDateFormat(string pattern)构造一个simpleDateFormat,使用指定的格式

常用方法:

常用方法说明
public final String format(Date date)格式化(日期对象->字符串)
public Date parse(String source)解析(字符串->日期对象)

在这里插入图片描述

  • 格式化日期对象
package API_.JDK7DateDome;

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

public class Dome2 {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf1 = new SimpleDateFormat();
        Date d1 = new Date(0L);
        String str1 = sdf1.format(d1);
        System.out.println(str1);

        SimpleDateFormat sdf2 = new SimpleDateFormat("YYYY年MM月dd HH时mm分ss秒 EE");
        Date d2 = new Date(0L);
        String str2 = sdf2.format(d2);
        System.out.println(str2);

        //1.定义一个字符串表示时间
        String s1 = "2022-11-11 18-12-00";
        //细节:
        //创建对象的格式要和字符串的格式完全一致
        SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date date = sdf4.parse(s1);
        System.out.println(date.getTime());
    }
}
  • 时间格式转换练习
package API_.JDK7DateDome;

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

public class Dome3 {
    public static void main(String[] args) throws ParseException {
        //2020-08-07 23:00:00
        String s1 = "2020-8-7 23:00:00";
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf1.parse(s1);
        //创建第二个SimpleDateFormat对象
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        String s2 =  sdf2.format(date);
        System.out.println(s2);
    }
}

3.3、JDK7时间-Calendar

  • Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年,月,日
  • 细节Calendar是一个抽象类,不能直接创建对象。

获取Calendar日历类对象方法

方法名说明
public static calendar getInstance()获取当前时间的日历对象

Calendar常用方法

方法名说明
public final Date getTime()获取日期对象
public final setTime(Date date)给日历设置日期对象
public long getTimeInMillis()拿到时间毫秒值
public void setTimeInMillis( long millis)给日历设置时间毫秒值
public int get(int field)取日历中的某个字段信息
public void set(int field,int value)修改日历的某个字段信息
public void add(int field,int amount)为某个字段增加/减少指定的值
  1. 获取日历对象
    • 细节1: calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象
    • 细节2:
      • 月份:范围0~11如果获取出来的是1那么实际上是2月。
      • 星期:1(星期日),2(星期一),3(星期二),4(星期三),5(星期四),6(星期五),7(星期六)
    • 底层原理:会根据系统的不同时区来获取不同的日历对象。把会把时间中的纪元,年,月,日,时,分,秒,星期,等等的都放到一个数组当中
    • 数组中的索引代表着不同的数据
    • Java底层通过常量使其替换数组来使可读性提高
      • ERA–0
      • TEAR–1
      • MONTH–2
      • WEEK_OF_YEAR–3
      • WEEK_OF_MONTH–4
      • DATE(DAY_OF_DATE)–5
      • DAY_OF_YEAR–6
      • DAY_OF_WEEK–7
package API_.JDK7DateDome;

import java.util.Calendar;
import java.util.Date;

public class Dome4 {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();

        Date d = new Date(0L);
        c.setTime(d);
        //修改时间的值
        //当设置的值超过给类型的上限(比如设置了999个月)组会将多余的月份转化为年
        c.set(Calendar.YEAR,1996);
        c.set(Calendar.MONDAY,11);
        c.set(Calendar.DAY_OF_MONTH,34);
        //增加某个字段的值
        c.add(Calendar.YEAR,2);
        //获取时间的年月日
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH)+1;
        int month2 = c.get(Calendar.MONDAY)+1;
        int date = c.get(Calendar.DAY_OF_MONTH);
        int day = c.get(Calendar.DAY_OF_WEEK);
        //打印
        System.out.println(year);
        System.out.println(month);
        System.out.println(month2);
        System.out.println(date);
        System.out.println(getDay(day));
    }
    public static String getDay(int index){
        String[] weekDay = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        return weekDay[index];
    }
}

四、JDK8时间

4.1、JDK8时间类

JDK7与JDK8相比

  1. 代码层面
    • JDK7:代码麻烦
      在这里插入图片描述
    • JDK8:简单 判断的方法,计算时间间隔的方法
  2. 安全层面
    • JDK7:多线程环境下会导致数据安全的问题
    • JDK8:时间日期对象都是不可变的,解决了这个问题

JDK8时间

  1. JDK8时间
    • ZoneId: 时区
    • Instant: 时间戳
    • ZoneDateTime: 带时区的时间
  2. 日期格式化类:
    SimpleDateFormat
    • DateTimeFormatter用于时间的格式化和解析
  3. 日历类:
    calendar
    • LocalDate:年、月、日
    • LocalTime:时、分、秒
    • LocalDateTime :年、月、日、时、分、秒
  4. 工具类
    • Duration:时间间隔(秒,纳秒)
    • Period:时间间隔(年,月,日)
    • ChronoUnit:时间间隔(所有单位)

4.2、Date类

ZoneId时区

方法名说明
static Set<String> getAvailableZoneIds()获取Java中支持的所有时区
static ZoneId systemDefault()获取系统默认时区
static ZoneId of(String zoneId)获取一个指定时区
package API_.JDK8DateDome;

import java.time.ZoneId;
import java.util.Set;

public class Dome1 {
    public static void main(String[] args) {
        //获取所有的地区时间ID
        Set<String> ZoneId1 = ZoneId.getAvailableZoneIds();
        System.out.println(ZoneId1.size());//602
        //System.out.println(ZoneId1);
        //获取默认地区的时间ID
        ZoneId zoneId2 = ZoneId.systemDefault();
        System.out.println(zoneId2);
        //获取指定的时区
        ZoneId zoneId3 = ZoneId.of("Asia/Chongqing");
        System.out.println(zoneId3);
    }
}

Instant时间戳

方法名作用
static Instant now( )获取当前时间的Instant对象(标准时间)
static Instant ofXxxx( long epochMilli)根据(秒/毫秒/纳秒)获取工Instant对象
ZonedDateTime atZone(ZoneId zone)指定时区
boolean isXxx(Instant otherInstant)判断系列的方法
Instant minusxxx( long millisToSubtract)减少时间系列的方法
Instant plusxxx( long millisToSubtract)增加时间系列的方法
package API_.JDK8DateDome;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Dome2 {
    public static void main(String[] args) {
        //获取当前时间的Instant对象(标准时间)
        Instant instant = Instant.now();
        System.out.println(instant);

        //根据(秒/毫秒/纳秒)获取Instant对象
        Instant instant2 = Instant.ofEpochMilli(0L);
        System.out.println(instant2);
        Instant instant3 = Instant.ofEpochSecond(1);
        System.out.println(instant3);
        Instant instant4 = Instant.ofEpochSecond(1,1000000000);
        System.out.println(instant4);

        //指定时区
        ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(time);

        //isXxx判断
        Instant instant5 = Instant.ofEpochMilli(2L);
        Instant instant6 = Instant.ofEpochMilli(3L);
        boolean b1 =  instant5.isBefore(instant6);
        boolean b2 =  instant5.isAfter(instant6);
        System.out.println(b1);
        System.out.println(b2);

        //减少时间系列的方法
        Instant instant7 = Instant.ofEpochMilli(3000L);
        Instant instant8 = instant7.minusSeconds(1);
        System.out.println(instant8);
        Instant instant9 = instant7.plusSeconds(1);
        System.out.println(instant9);
    }
}

ZoneDateTime带时区的时间

方法名说明
static ZonedDateTime now()获取当前时间的ZonedDateTime对象
static ZonedDateTime ofXxxx(。。。)获取指定时间的ZonedDateTime对象
ZonedDateTime withXxx(时间)修改时间系列的方法
ZonedDateTime minusXxx(时间)减少时间系列的方法
ZonedDateTime plusxxx(时间)增加时间系列的方法
package API_.JDK8DateDome;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Dome3 {
    public static void main(String[] args) {
        //创建一个ZonedDateTime时间对象
        ZonedDateTime time1 = ZonedDateTime.now();
        System.out.println(time1);//2023-04-22T19:46:37.067646400+08:00[Asia/Shanghai]

        //创建一个指定时间对象
        ZonedDateTime time2 = ZonedDateTime.of(2023,4,22,19,50,
                30,0, ZoneId.of("Asia/Shanghai"));
        System.out.println(time2);
        //通过Instant+时区的方式指定获取的时间对象
        Instant instant = Instant.ofEpochMilli(0L);
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        ZonedDateTime time = ZonedDateTime.ofInstant(instant,zoneId);
        System.out.println(time);
        //修改时间
        ZonedDateTime time3 = time.withYear(2000);
        //增加时间
        ZonedDateTime time4 = time3.minusYears(1);
        //减少时间
        ZonedDateTime time5 = time3.plusYears(1);
        System.out.println(time3);
        System.out.println(time4);
        System.out.println(time5);

    }
}

细节:
JDK8新增的时间对象都是不可变的如果我们修改了,减少了,增加了时间那么调用者是不会发生改变的,产生一个新的时间。

4.3、日期格式化类

DateTimeFormatter 用于时间的格式化和解析

方法名说明
static DateTimeFormatter ofPattern(格式)获取格式对象
String format(时间对象)按照指定方式格式化
package API_.JDK8DateDome;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Dome4 {
    public static void main(String[] args) {
        ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss EE a");

        System.out.println(dtf.format(time));
    }
}

4.4、日历类

LocalDate、LocalTime、LocalDateTime

方法名说明
static xxx now()获取当前时间的对象
static xxx of(。。。)获取指定时间的对象
get开头的方法获取日历中的年、月、日、时、分、秒等信息
isBefore,isAfter比较两个LocalDate
with开头的修改时间系列的方法
minus开头的减少时间系列的方法
plus开头的增加时间系列的方法
  • get方法中,LocalDate只能获取年月日,LocalTime只能获取时分秒
  • LocalDateTime可以转化为LocalDate、LocalTime
方法名说明
public LocalDate toLocalDate()LocalDateTime转换成一个LocalDate对象
public LocalTime toLocalTime()LocalDateTime转换成一个LocalTime对象
package API_.JDK8DateDome;

import javax.xml.stream.Location;
import java.time.*;

public class Dome5 {
    public static void main(String[] args) {
        //获取日期
        LocalDate localDate = LocalDate.now();
        LocalDate localDate2 = LocalDate.of(2000,10,1);
        System.out.println(localDate);
        //获取年份
        int y = localDate.getYear();
        System.out.println(y);
        //获取月份
        Month m = localDate.getMonth();
        System.out.println(m);
        int m1 = m.getValue();
        System.out.println(m1);
        int date = localDate.getDayOfYear();
        int date2 = localDate.getDayOfMonth();
        System.out.println(date);
        System.out.println(date2);
        //获取星期数
        DayOfWeek dayOfWeek = localDate.getDayOfWeek();
        System.out.println(dayOfWeek);
        //比较日期
        System.out.println(localDate.isAfter(localDate2));
        System.out.println(localDate.isBefore(localDate2));
        //修改日期
        LocalDate localDate1 = localDate2.withYear(2021);
        System.out.println(localDate1);
        //增减日期
        LocalDate localDate3 = localDate2.minusYears(1);
        LocalDate localDate4 = localDate2.plusYears(1);
        System.out.println(localDate3);
        System.out.println(localDate4);

        LocalDate birthday = LocalDate.of(2000,4,23);
        LocalDate newDay = LocalDate.now();

        MonthDay bir = MonthDay.of(birthday.getMonth(),birthday.getDayOfMonth());
        MonthDay new1 = MonthDay.of(newDay.getMonth(),newDay.getDayOfMonth());
        System.out.println(bir.equals(new1));

    }
}

4.5、工具类

Period——用于计算两个“日期”间隔(年、月、日)
Duration——用于计算两个“时间”间隔(秒,纳秒)
ChronoUnit——用于计算两个“日期”间隔

Period

package API_.JDK8DateDome;

import java.time.LocalDate;
import java.time.Period;

public class Dome6 {
    public static void main(String[] args) {
        LocalDate toDay = LocalDate.now();
        System.out.println(toDay);

        LocalDate birthday = LocalDate.of(2000, 1, 1);

        Period period = Period.between(birthday,toDay);
        System.out.println(period);
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
        //相距的月份
        System.out.println(period.toTotalMonths());
    }
}

Duration

package API_.JDK8DateDome;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;

public class Dome7 {
    public static void main(String[] args) {
        LocalDateTime toDay = LocalDateTime.now();

        System.out.println(toDay);

        LocalDateTime birthday = LocalDateTime.of(2000, 1, 1,1,0,00,00);

        Duration Duration1 = Duration.between(birthday,toDay);
        System.out.println(Duration1);
        System.out.println(Duration1.getSeconds());
        System.out.println(Duration1.getNano());
        //相距
        System.out.println(Duration1.toDays());
        System.out.println(Duration1.toHours());
        System.out.println(Duration1.toMillis());
        System.out.println(Duration1.toDaysPart());
        System.out.println(Duration1.toNanos());
    }
}

ChronoUnit

package API_.JDK8DateDome;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class Dome8 {
    public static void main(String[] args) {
        LocalDateTime today = LocalDateTime.now( );
        System.out.println(today ) ;
        //生日时间
        LocalDateTime birthDate = LocalDateTime.of( 2000,1, 1,0,0,0,0) ;
        System.out.println(birthDate);
        System.out.println("相差的年数: " + ChronoUnit.YEARS.between(birthDate,today));
        System.out.println("相差的月数: " + ChronoUnit.MONTHS.between(birthDate,today));
        System.out.println("相差的周数: " + ChronoUnit.WEEKS.between(birthDate,today));
        System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate,today));
        System.out.println("相差的时数: " + ChronoUnit.HOURS.between(birthDate,today));
        System.out.println("相差的分数:" +ChronoUnit.MINUTES.between(birthDate,today));
        System.out.println("相差的秒数: " + ChronoUnit.SECONDS.between(birthDate,today));
        System.out.println("相差的毫秒数:" +ChronoUnit.MILLIS.between(birthDate,today));
        System.out.println("相差的微秒数:" +ChronoUnit.MICROS.between(birthDate,today));
        System.out.println("相差的纳秒数: " + ChronoUnit.NANOS.between(birthDate,today));
        System.out.println("相差的半天数: " + ChronoUnit.HALF_DAYS.between(birthDate,today));
        System.out.println("相差的十年数:" +ChronoUnit.DECADES.between(birthDate,today));
        System.out.println("相差的世纪(百年)数: " + ChronoUnit.CENTURIES.between(birthDate,today));
        System.out.println("相差的千年数: " +ChronoUnit.MILLENNIA.between(birthDate, today));
        System.out.println("相差的纪元数: " + ChronoUnit.ERAS.between(birthDate,today));

    }
}

五、包装类

包装类:用一个对象,把基本数据类型给包起来

Integer.valueOf()创建int型数据与new Integer()创建int型数据的区别

当用Integer.valueOf()创建的数据大于127时就会出现两个相同数值的变量不相同
底层原理:
因为在实际开发中,-128~127之间的数据,用的比较多。如果每次使用都是new对象,那么太浪费内存了
所以,提前把这个范围之内的每一个数据都创建好对象如果要用到了不会创建新的,而是返回已经创建好的对象。

在JDK5的时候提出了一个机制:

  • 自动装箱和自动拆箱
  • 自动装箱:把基本数据类型会自动的变成其对应的包装类
  • 自动拆箱:把包装类自动的变成其对象的基本数据类型
  • 在JDK5之后,int和integer可以看作是一个东西,因为在其内部可以自动转化

Integer成员方法

方法名说明
public static String toBinaryString(int i)得到二进制
public static String toOctalString(int i)得到八进制
public static String toHexString(int i)得到十六进制
public static int parselnt(String s)将字符串类型的整数转成int类型的整数
package API_.Integer;

public class Dome2 {
    public static void main(String[] args) {
        String str1 = Integer.toBinaryString(123);
        String str2 = Integer.toOctalString(123);
        String str3 = Integer.toHexString(123);

        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);

        int i = Integer.parseInt("123");
        System.out.println(i+1);
    }
}

  • 细节1:
    在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
  • 细节2:
    8种包装类当中,除了character都有对应的parsexxx的方法,进行类型转换

键盘录入改进
在键盘录入时使用nextLine方法

  • 这种方法的特点是只有遇到回车才会停止

六、综合练习

6.1、键盘录入

在这里插入图片描述

package API_;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Test1 {
    public static void main(String[] args) {
        //创建一个集合
        ArrayList<Integer> arr  = new ArrayList<>();
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("请输入一个整数(1~200)");
            String num0 = sc.nextLine();
            int num = Integer.parseInt(num0);
            if(num<1||num>200){
                System.out.println("输入的数字不符合要求");
            }
            //将符合要求的数字存到集合中
            arr.add(num);
            int sum = getSum( arr , num);
            if(sum>200){
                break;
            }
        }
        //遍历集合
        for (int i = 0; i < arr.size(); i++) {
            System.out.print(arr.get(i)+" ");
        }
    }
    //对集合里面的数字进行相加求和
    private static int getSum(ArrayList<Integer> arr, int num) {
        int sum = 0;
        for (int i = 0; i < arr.size(); i++) {

            sum = sum + num;
        }
        return sum;
    }
}

6.2、算法水题

在这里插入图片描述

package API_;

import java.util.Scanner;

public class Test2 {
    public static void main(String[] args) {
        System.out.println("请输入整数");
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        //利用正则表达式验证该字符串是否符合要求
        if(!str.matches("[1-9]\\d{0,9}")){
            System.out.println("输入的整数不符合规则");
        }else {
            int number = 0;
            for (int i = 0; i < str.length(); i++) {
                //将字符转化成数字
                int num = str.charAt(i) - '0' ;
                number = number*10 + num;
            }
            System.out.println(number);
        }
    }
}

6.3、算法水题

在这里插入图片描述

package API_;

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

        System.out.println(toBinaryString(3));
    }
    public static String toBinaryString(int num){
        //创建一个字符空间
        StringBuilder sb = new StringBuilder();

        while (true){
            //判断传入的数字是不是0
            if(num ==0){
                break;
            }
            int number = num%2;
            //将每次循环的到的新的数字放置这个字符空间的首位
            sb.insert(0,number);
            num = num/2;
        }
        return sb.toString();
    }
}

6.4、算法水题

在这里插入图片描述

package API_;

import javax.lang.model.element.NestingKind;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.regex.Pattern;

public class Test4 {
    public static void main(String[] args) throws ParseException {
        //JDK7计算出生时间差
        String birthday = "2000-01-01";
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd");
        Date date = sdf.parse(birthday);
        long birthdaytime = date.getTime();
        long today = System.currentTimeMillis();

        long time = today-birthdaytime;
        System.out.println(time/1000/60/60/24);

        //JDK8计算出生时间差
        LocalDate localDate = LocalDate.of(2000,1,1);
        LocalDate localDate1 = LocalDate.now();

        System.out.println(ChronoUnit.DAYS.between(localDate, localDate1));

    }
}

6.5、算法水题

在这里插入图片描述

package API_;

import java.time.LocalDate;
import java.util.Calendar;

public class Test5 {
    public static void main(String[] args) {
        //用JDK7判断闰年平年
        Calendar calendar = Calendar.getInstance();
        calendar.set(2000,2,1);
        //将日期往前减一天
        calendar.add(Calendar.DAY_OF_MONTH,-1);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(day);

        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(2001,0,1);
        //日期往前减一天
        calendar1.add(Calendar.DAY_OF_YEAR,-1);
        int day1 = calendar1.get(Calendar.DAY_OF_YEAR);
        System.out.println(day1);

        //JDK8
        LocalDate d1 = LocalDate.of(2000,3,1);
        LocalDate d2 = d1.minusDays(1);
        int dayOfMonth = d2.getDayOfMonth();
        System.out.println(dayOfMonth);

        //JDK8中有专门的方法判断是否为闰年
        //true:闰年
        //false:平年
        System.out.println(d1.isLeapYear());

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值