一,Scanner类

Scanner 类可以从键盘中录入数据

Scanner sc=new Scanner(System.in);//创建方法
//常用方法
String s=sc.next();//获取字符串,但是遇到空格,回车,tab制表符就停止了
//比如说123 abc就只能读取到123
String s1=sc.netxLine();//遇到回车才停止,解决了next的不足
 
nextInt();
nextDouble();
nextXXX;
//获取对应的基本数据类型

二,字符串

2.1 字符串的比较

  • 关于 == 比较的是什么

    1. 当比较的是基本数据类型,比的是数据值
    2. 当比较的是引用数据类型,比的是地址值
  • 字符串比较

    boolean equals(要比较的字符串);//完全一样才是true
    boolean equalsIgnoreCase(要比较的字符串);//不看大小写的比较
    String a="aaa",b="ccc";
    a.equals(b);
    

2.2 StringBuilder

StringBuilder 是一个内容可变的容器,用来提高字符串的操作效率

  • StringBuilder 构造方法

    public StringBuilder();//创建一个空白的容器
    public StringBuilder(String str);//根据字符串内容来创建可改变的字符串对象
    
  • StringBuilder 常用的方法

    public int length();//返回长度
    public String toString();//通过toString()将StringBuilder转换为String
    public int indexOf(String str);//查询字串str在主串的索引下标,找不到返回-1
    public StringBuilder insert(int 起始索引,String 要替换的字串);//插入
    public StringBuilder replace(int 起始索引,int 终点索引,String 要插入的字符串);//替换
    public StringBuilder delete(int 起始索引,int 终点索引);//删除内容
    public StringBuilder append(任意类型);//添加数据
    public StringBuilder reverse();//反转内容
    public String substring(int 起始索引,int 终点索引);//剪切,并且返回String
    public boolean isEmpty();//判断是否为空
    

    java 底层对 StringBuilder 做了特殊处理,打印对象的时候出现的是里面的内容

    一种链式编程写法:

    StringBuilder sb=new StringBuilder();
    sb.append("Hello").append("World").append("Java");
    System.out.println(sb);
    

2.3 StringJoiner

StringJoiner 和 StringBuilder 一样,是一个内容可变的容器

作用:提高字符串的操作效率,并且简化代码。

  • StringJoiner 的构造方法

    public StringJoiner(字符串间的间隔符号);//创建一个StringJoiner对象,指定间隔符号
    public StringJoiner(间隔符号,开始符号,结束符号);//创建一个StringJoiner对象,指定开始,结束,间隔符号
    
  • StringJoiner 的方法

    public int length();//返回容器长度
    public StringJoiner merge(String Joiner);//将其他StringJoiner的内容合并进来,只是合并内容,分隔符和其他的是不合并的
    public String toString();//把StringJoiner变为String
    public StringJoiner add(添加内容);//添加数据并返回内容本身
    

2.4 StringBuffer

StringBuffer 所有的方法和 StringBuilder 完全一模一样。

区别就是,StringBuilder 是线程不安全的StringBuffer 是线程安全的。

如果说需要同步,就使用 StringBuffer

StringBuffer 里面所有的方法都是同步方法,使用多线程的时候一般使用 StringBuffer

2.5 String类

  1. String在java.lang.String中,不需要自己创建
  2. 在java中随便使用 双引号括起来 的都是String对象。
  3. String类一旦创建是不可修改的!
  4. "abc"这种双引号括起来的字符串,存储在方法区中的字符串常量池中!
  • 常用构造方法
方法说明
String s="hello"直接赋值
public String(String val)通过传递的字符串来构造
public String(char[] chars)通过传递的字符数组来构造
public String(byte[] chars)通过传递的字节数组来构造
  • 常用的方法
  1. 求取字符串长度
public int length() // 返回该字符串的长度
  1. 根据索引求字符串内的字符
public char charAt(int index)   //   返回字符串中指定位置的字符;注意字符串中第一个字符索引是0,最后一个是length()-1。
  1. 字符串的截取
// 用String类的substring方法可以提取字符串中的子串,该方法有两种常用参数:
public String substring(int beginIndex) // 该方法从beginIndex位置起,从当前字符串中取出剩余的字符作为一个新的字符串返回。
public String substring(int beginIndex, int endIndex) // 该方法从beginIndex位置起,从当前字符串中取出到endIndex-1位置的字符作为一个新的字符串返回。
  1. 字符串的比较
public int compareTo(String anotherString)
 //该方法是对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。
    
public int compareToIgnore(String anotherString)//与compareTo方法相似,但忽略大小写。
    
public boolean equals(Object anotherObject)//比较当前字符串和参数字符串,在两个字符串相等的时候返回true,否则返回false。
    
public boolean equalsIgnoreCase(String anotherString)//与equals方法相似,但忽略大小写。
  1. 字符串的拼接
public String concat(String str) // 将参数中的字符串str连接到当前字符串的后面,效果等价于"+"。
  1. 查找字符串中子串的索引
public int indexOf(int ch/String str)//用于查找当前字符串中字符或子串,返回字符或子串在当前字符串中从左边起首次出现的位置,若没有出现则返回-1。
public int indexOf(int ch/String str, int fromIndex)//改方法与第一种类似,区别在于该方法从fromIndex位置向后查找。
    
    
public int lastIndexOf(int ch/String str)//该方法与第一种类似,区别在于该方法从字符串的末尾位置向前查找。
public int lastIndexOf(int ch/String str, int fromIndex)//该方法与第二种方法类似,区别于该方法从fromIndex位置向前查找。
  1. 字符串大小写转换
public String toLowerCase()//返回将当前字符串中所有字符转换成小写后的新串
public String toUpperCase()//返回将当前字符串中所有字符转换成大写后的新串
  1. 字符串中字符的替换
public String replace(char oldChar, char newChar) //用字符newChar替换当前字符串中所有的oldChar字符,并返回一个新的字符串。
public String replaceFirst(String regex, String replacement)//把第一个符合正则表达式的子字串替换为replacement,并返回新的字符串
public String replaceAll(String regex, String replacement)//把符合正则表达式的字符串全部替换为replacement,并返回新的字符串
  1. 其他方法
public String trim() //将字符串前后空白字符减去,并返回新的字符串
public boolean isEmpty()  // 判断字符串是否为空,为空就返回true
public boolean contains(String str)  //判断是否包含Str.是就返回true
public char[] toCharArray() // 将字符串返回为字符数组
public boolean startsWith(String prefix) // 测试此字符串是否以指定的子串开始,是就返回true
public boolean endsWith(String prefix) // 测试此字符串是否以指定的子串结束,是就返回true
public String[] split(String regex,int limit) // 根据匹配给定的正则表达式来拆分此字符串,并且返回字符串数组
public byte[] getBytes();//将字符串转化为字节数组

三,Math类

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

    Math 类常用的方法

方法名说明
public static int abs(int a)获取绝对值
public static double ceil(double a)向上取整
public static double floor(double a)向下取整
public static int round(float a)四舍五入
public static int max(int a,int b)获取最大值
public static int min(int a,int b)获取最小值
public static double pow(double a,double b)返回a的b次幂的值
public static double sqrt(double a)a开平方根
public static double cbrt(double a)a开立法根
public static double random()返回double类型的随机数范围是[0.0,1.0)

abs 方法有 bug!

以 int 为例,假设 int 的取值范围为 -11 到 10

abs(-11) 打印出来的也是 -11

即如果没有正数与负数对应,那么传递负数结果有误

解决方法:用absExact方法 (jdk15 出现的),当没有正数和负数对应的时候会报错 ~

四,System类

  • 工具类,提供了一些和系统相关的方法

常用方法:

方法名说明
public static void exit(int status)终止当前运行的java虚拟机,状态码:0表示虚拟机是正常停止的,非0表示当前虚拟机异常停止
public static long currentTimeMillis()返回当前系统的时间(以毫秒形式)用来计算代码运行时间这个方法返回自1970年1月1日0时0分0秒(UTC)以来的毫秒数
public static void arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数)数组拷贝(浅拷贝)
int [] arr1={1,2,3,4,5,6,7,8,9,10};
int[] arr2=new int[10];
//把arr1数组数据拷贝到arr2中
System.arraycopy(arr1,0,arr2,0,10);
//参数一:数据源:要拷贝的数据从哪个数组来
//参数二:从数据源数组中第几个索引开始拷贝
//参数三:目的地:我要把拷贝的数组拷贝到哪个数组中
//参数四:目的地数组的索引
//参数五:拷贝的个数

如果数据源数组和目的地数组都是基本数据类型,那么两者的类型必须保持一致

在拷贝的时候,需要考虑数组的长度

如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型

五,Runtime类

Runtime 表示当前虚拟机的运行环境

这个类的方法不是静态的,需要获取对象调用里面的方法

获取对象方法

//java规定了runtime只能有一个对象
Runtime r1=Runtime.getRuntime();
Runtime r2=Runtime.getRuntime();
//r1和r2是同一个对象

常用方法

方法名说明
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 freeMemroy()JVM剩余内存大小(byte)
public Process exec(String command)运行cmd命令

Runtime 的 exit 就是 System 的 exit 的底层源码

Runtime.exec() 不是 cmd 或 shell 环境,因此无法直接调用 dir 等命令。若要调用命令行下的命令,请参考

Runtime runtime = Runtime.getRuntime();
Process pwd = runtime.exec("cmd pwd");

六,Object类

  • Object 是 java 中顶级父类,所有类都是直接或间接继承于 Object 类

  • Object 类中方法可以被所有子类访问

Object 类的构造方法

public Object()//只有空参构造
  • 常见方法
//把对象转换成字符串,对象的字符串是地址值,,一般会自己重写打印对象的属性值
//如果我们打印一个对象,想看到对象内的属性值,需要重写toString方法
public String toString();

public boolean equals(Object b);//比较俩个对象的地址值是否相等

portected Object clone();//对象克隆,把A对象的属性值完全拷贝给B对象(浅拷贝)

Object 类中的 equals 默认比较俩对象地址值,一般它的子类都会重写 equals 方法!

比如说 String 类中的 equals 是重写了的,会先判断是否为字符串,如果是字符串再比较内部的属性,如果不是字符串直接返回 false

StringBuilder 类中的 equals 是直接继承 Object 类中的 equals,这个 equals 用 == 号比较俩个对象的地址值

  • 使用 clone 方法

    需要在子类中

    • 重写clone方法,用super.clone()来调用
    • 在子类中实现Cloneable接口,这个接口是个标记接口(即里面没有方法的接口)
    • 还需要注意,这个是返回Object类的对象,需要强转
  • Java2 种克隆方式:

    1. 浅克隆(Object中的clone)
      2953321-20230310215655640-2114556011.png
    2. 深克隆
      2953321-20230310215637606-1986513359.png

    深克隆是自己在子类中重写的,但是有第三方工具可以帮助我们实现

七,Objects类

Objects 是一个工具类,提供了一些方法去完成一些功能

Objects 的成员方法中常用的

方法名说明
public static boolean equals(Object a,Object b)先做非空判断,再比较对象
public static boolean isNull(Object object)判断对象是否为null,如果是返回true
public static boolean notNull(Object obj)判断对象是否为null,如果是返回false

在 java 中不能用 null 来调用方法!会报错:空指针异常

equals 方法底层会判断 a 是否为 null**,如果为 null,返回 false**,如果不为 null 就利用 a 调用 equals 方法

如果没有重写,比较的是地址值,如果重写了就比较属性值

八,BigInteger类

在 java 中正数有:byte,short,int,long 他们字节分别为 1,2,4,8 长度很短

当我们需要存储的数据远大于 long 类型的整数就需要使用 BigInteger 类了

  • BigInteger构造方法
方法名说明
public BigInteger(int num,Random rand);获取随机的大整数,范围:[0~2的num次方-1]
public BigInteger(String val);获取指定大的整数
public BigInteger(String val,int radix);获取指定进制的大整数

对象一旦创建!内布记录的值不可改变!!

除了整数,写别的会报错!!

获取指定进制的必须和对应进制吻合!比如说二进制只能为 0 和 1 不能出现 2!!

  • 常用方法
方法名说明
public static BigInteger valueOf(long val)静态方法获取BigInteger对象,内部有优化
public BigInteger add(BigInteger val)
public BigInteger substract(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 val)次幂
public BigInteger max(BigInteger val)返回最大值
public BigInteger min(BigInteger val)返回最小值
public int intValue(BigInteger val)转为int类型,超出范围会造成数据错误~
Value之外还可转成byte,short,long,double修改xxxValue即可

获取 BigInteger 对象这个方法,val 只能为 long 类型大小

在内部对常用的数字:-16~16进行了优化

会提前把 -16~16 先创建好 BigInteger 对象,如果多次获取就不会重写创建,一般数据在 -16 到 16 就用这个方法获取对象

BigInteger 在进行运算的时候是创建一个新的 BigInteger 对象并存储而不是修改原来调用者对象!

九,BigDecimal类

例:

System.out.println(0.09+0.01);
System.out.println(0.216-0.1);
System.out.println(0.226*0.01);

上述代码输出的时候都会得到错误数据,这都是因为计算机中小数存储的原因

9.1 计算机中的小数存储

在计算机中不管是运算还是存储都是转化为二进制存储的

如:
2953321-20230310223534597-1179937031.png
2953321-20230310223551467-1041593870.png
2953321-20230310223604942-112285385.png
如图可知,小数部分二进制位太大了,这些基本数据类型无法存储,多出的部分就会舍去,导致小数计算不精确

要进行小数的精确运算,就通过 BigDecimal 这个类实现

9.2 BigDecimal

作用:

  • 用来进行小数间精确运算
  • 用来表示很大的小数

常用构造方法

方法名说明
public BigDecimal(double val)通过传递double类型的数据构造,这个构造方法会造成不精确结果,不建议使用
public BigDecimal(String val)通过传递的字符串来构造,这个结果是精确的!

常用方法

方法名说明
public static BigDecimal valueOf(double val)传递double类型的val获取BigDecimal对象
public static BigDecimal add(BigDecimal val)
public static BigDecimal substract(BigDecimal val)
public static BigDecimal multiply(BigDecimal val)
public static BigDecimal divide(BigDecimal val)
public static BigDecimal divide(BigDecimalval,精确到第几位,舍入模式)

如果表示的数字不大,没有超过 double 取值范围,建议使用静态方法,超出了建议使用构造方法

如果传递的是0 到 10 之间的整数,包含 0 和 10,那么方法会返回已经创建好的对象,不需要 new 了!

BigDecimal 类也是和 BigInteger 类一样创建了无法更改内容的,进行运算也是 new 一个新的 BigDecimal 进行存储的

  • 舍入模式:

    在 jdk 新版本中定义在RoundingMode类中,有:

    UP 远离零方向的舍入模式 比如说 -1.1 就是 -2

    DOWN 靠近零方向的舍入模式 比如 -1.1 就是 -1

    CEILING 向正无穷大方向的舍入模式 比如 5.5 就是 6

    FLOOR 向负无穷大方向的舍入模式 比如 5.5 就是 5

    HALF_UP 四舍五入 (一般默认用这个)

RoundingMode是工具类,使用这些舍入模式方法就是

RoundingMode.UP这样

BigDecimal divide(BigDecimalval,3,RoundingMode.UP)这样写即可

十,时间类

前置知识点:

  • 以前使用GMT(格林尼治)时间作为标准时间
  • 现在使用铯原子震动时间作为标准时间
  • 中国标准时间是标准时间+8h
  • 1s=1000毫秒,1毫秒=1000微秒,1毫秒=1000纳秒

11.1 JDK7之前的时间类

11.1.1 Date类:

Date 类是一个 JDK 写好的 javabean 类,用来描述时间,精确到毫秒

可以对时间进行数学运算获取时间的先后

直接打印出来就是对应的时间

构造方法:

public Date();//创建Date对象,这个对象表示当前时间
public Date(long date);//创建时间对象,表示指定时间
Date d=new SimpleDateFormat("yyyy年MM月dd日").parse("2000年1月1日");//新写法

常用方法:

public void setTime(long time);//设置/修改毫秒值
public long getTime();//获取时间的毫秒值

11.1.2 SimpleDateFormat类

SimpleDateFormat 类的作用:

  • 格式化:把时间变成自己习惯的格式
  • 解析:把字符串表示的时间变成Date对象

构造方法

public SimpleDateFormat();//构造一个SimpleDateFormat,使用java默认格式
public SimpleDateFormat(String pattern);//构造一个SimpleDateFormat,使用指定的格式

常用方法

Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//把Date格式化为指定格式的String
String format = sdf.format(date);
System.out.println(format);
//把指定字符串格式化为Date
Date parseDate = sdf.parse("2020-07-01 00:00:00");
System.out.println(parseDate);

11.1.3 Calendar类

Calendar 表示系统当前时间的日历对象,可以单独修改,获取时间中的年,月,日

细节:Calendar 是一个抽象类,不能直接创建对象

打印出来 Calendar 对象获取的是一个数组,里面存储了年月日等信息

获取对象方法

public static Calendar getInstance();//获取当前时间的日历对象

底层原理:会根据系统的不同时区获取不同的日历对象

会把时间中的:纪元,年,月,日,时,分,秒,星期等都放入一个数组当中

细节:

Calendar 类的月份范围:0~11 即 0 代表 1 月,1 代表 2 月......

Calendar 星期范围:(在外国人眼中,星期天代表的是一周的第一天) 1(星期天) 2(星期 1) 3(星期二)

常用方法

//这里的field写的就是上面的数字了
public void set(int field,int value);//修改日历的某个字段信息
//如果我们在set方法中设置比如说13月,那么会自动12进制进位加1年加1月这样的方式哦
public void add(int field,int amount);//为某个字段增加/减少指定值      
//amount负数就是减,正数就是加
public void get(int field);//获取日历类数组中的数据

field 填写如下

  • 0:纪元

  • 1:年

  • 2:月

  • 3:一年中的第几周

  • 4:一个月中的第几周

  • 5:一个月中的第几天(日期)

  • 6:一年中的第几天

  • 7:一周中的第几天

但是在 java 中,Calendar 类把这些数字定义成了常量!

  • 1-->YEAR
  • 2--->MONTH
  • 3--->WEEK_OF_YEAR
  • 4---->WEEK_OF_MONTH
  • 5---->DATE
  • 6--->DAY_OF_YEAR
  • 7:DAY_OF_WEEK

可以通过Calendar.XXX常量名调用而不是通过数字,更多的可以看源码。

11.2 JDK8开始的时间类

  • 使用 JDK8 时间类的原因

    JDK7 的时间类在计算或比较日期对象都需要转化为毫秒值,很麻烦,并且在多线程环境下会导致数据安全的问题。

    JDK8 简化了日期对象的计算或比较,并且 JDK8 的时间日期对象都是不可变的,不会产生多线程环境下造成的数据不安全情况。

    这些 jdk8 的时间类总体上就是对时间的

  • 获取:now,of创建对象,getXXX 获取指定时间信息

  • 修改:withXXX 来进行修改

  • 加:plusXXX 进行添加

  • 减:minusXXX 进行减

  • 判断:isAfter,isBefore,equals进行判断

  1. 日期类:代替Calendart的
    • LocalDate:年,月,日,星期
    • LocalTime:时,分,秒,纳秒
    • LocalDateTime:年,月,日,星期,时,分,秒,纳秒
    • ZoneId:时区
    • ZonedDateTime:带时区的时间
  2. 代替Date的:
    • Instant:时间线上的某个时刻/时间戳
  3. 代替SimpleDateFormat的:
    • DateTimeFormatter:格式化器,用于时间的格式化,解析。
  4. 常用工具类
    • Period:计算日期间隔(年,月,日)
    • Duration:计算时间间隔(时,分,秒,纳秒)

11.2.1 日期类

他们获取对象的方法:

方法名示例
public static Xxx now();//获取系统当前时间对应的该对象LocalDate id=LocalDate.now()
LocalTime id=LocalTime .now()
LocalDateTime id=LocalDateTime .now()
public static Xxx of(年,月,日,时,分,秒,纳秒)//指定时间创建对象LocalDateTime ld=LocalDateTime.of(2023,12,12,12,12,12);
LocalDate ld1=LocalDate.of(2019,1,1);
LocalTime ld2=LocalTime.of(12,12,12);

常用方法

  1. 获取日期对象中的信息
LocalDateTime date = LocalDateTime.now();
int year = date.getYear();//年
int monthValue = date.getMonthValue();//月(1-12)
int dayOfMonth = date.getDayOfMonth();//日
int dayOfYear = date.getDayOfYear();//一年中的第几天
int value = date.getDayOfWeek().getValue();//星期几
  1. 直接修改某个信息
LocalDateTime date = LocalDateTime.now();
LocalDateTime ld1 = date.withYear(2099);//修改年
LocalDateTime ld2 = date.withMonth(12);//修改月
LocalDateTime ld3 = date.withDayOfMonth(22);//修改日
LocalDateTime ld4 = date.withDayOfYear(2);//修改一年中的第几天
LocalDateTime ld5 = date.withHour(12);//修改时
LocalDateTime ld6 = date.withMinute(30);//修改分
LocalDateTime ld7 = date.withSecond(2);//修改秒
LocalDateTime ld8 = date.withNano(3);//修改纳秒
  1. 加(plusXXX),减(minusXXX)
//减就是将plus改成minus
LocalDateTime date = LocalDateTime.now();
LocalDateTime ld1 = date.plusYears(2);//加年
LocalDateTime ld2 = date.plusMonths(2);//加月
LocalDateTime ld3 = date.plusDays(20);//加日
LocalDateTime ld4 = date.plusWeeks(3);//加星期
LocalDateTime ld5 = date.plusHours(3);//加时
LocalDateTime ld6 = date.plusMinutes(3);//加分
LocalDateTime ld7 = date.plusSeconds(3);//加秒
LocalDateTime ld8 = date.plusNanos(3);//加纳秒
  1. 判断
LocalDateTime ld1 = LocalDateTime.now();
LocalDateTime ld2 = LocalDateTime.of(2019, 1, 1, 0, 0, 0)
System.out.println(ld1.equals(ld2));//判断ld1是否等于ld2
System.out.println(ld1.isEqual(ld2));//判断ld1是否等于ld2
System.out.println(ld1.isAfter(ld2));//判断ld1是否在ld2之后
System.out.println(ld1.isBefore(ld2));//判断ld1是否在ld2之前
  1. 转换
//LocalDateTime可以转化成LocalDate或LocalTime
LocalDateTime ld = LocalDateTime.now();
LocalDate localDate = ld.toLocalDate();
LocalTime localTime = ld.toLocalTime();

11.2.2 带时区的时间

ZoneId:代表时区 Id

用:州名/城市名,国家名/城市名 表示

举例:Asia/ShangHai,America/New_York

ZoneId 用法:

ZoneId zoneId = ZoneId.systemDefault();//获取系统默认时区
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();//获取所有java支持的时区集合
ZoneId zoneId1 = ZoneId.of("America/New_York");//获取指定时区的zoneId对象

ZonedDateTime:带时区的时间

ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId);//获取美国纽约的时间(带时区)
ZonedDateTime now = ZonedDateTime.now(Clock.systemUTC());//获取世界标准时间
ZonedDateTime now2 = ZonedDateTime.now();//获取系统默认时区的时间

常用方法:

//1.获取,年月日时分秒
int year = zonedDateTime.getYear();
int month = zonedDateTime.getMonthValue();
int day = zonedDateTime.getDayOfMonth();
int hour = zonedDateTime.getHour();
int minute = zonedDateTime.getMinute();
int second = zonedDateTime.getSecond();
int dayOfMonth = zonedDateTime.getDayOfMonth();//获取当前是这个月的第几天
int value = zonedDateTime.getDayOfWeek().getValue();//获取当前是这周的第几天
int dayOfYear = zonedDateTime.getDayOfYear();//获取当前这个年的第几天
//2.修改(plusXXX加,minusXXX减法,withXXX修改)
ZonedDateTime zonedDateTime1 = zonedDateTime.plusYears(1);
ZonedDateTime zonedDateTime2 = zonedDateTime.plusMonths(1);
ZonedDateTime zonedDateTime3 = zonedDateTime.plusDays(1);
ZonedDateTime zonedDateTime4 = zonedDateTime.plusHours(1);
ZonedDateTime zonedDateTime5 = zonedDateTime.plusMinutes(1);
ZonedDateTime zonedDateTime6 = zonedDateTime.plusSeconds(1);
ZonedDateTime zonedDateTime7 = zonedDateTime.plusNanos(1);

11.2.3 时间戳Instant

通过获取 Instant 的对象可以拿到此刻的时间,该时间由两部分组成: 从1970-01-01 00:00:00 开始走到此刻的总秒数 + 不够 1 秒的纳秒数

**Instant 的作用:** 可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点

传统的 Date 类,只能精确到毫秒,并且是可变对象;

新增的 Instant 类,可以精确到纳秒,并且是不可变对象,推荐用 Instant 代替 Date。

Instant now = Instant.now();//创建Instant对象,获取当前时间信息
//获取
long epochSecond = now.getEpochSecond();//获取总秒数
int nano = now.getNano();//获取不够1秒的纳秒值
//加        
Instant instant = now.plusSeconds(1);//加1秒
Instant instant1 = now.plusMillis(1);//加1毫秒
Instant instant2 = now.plusNanos(1);//加1纳秒
//减
Instant instant3 = now.minusSeconds(1);//减1秒
Instant instant4 = now.minusMillis(1);//减1毫秒
Instant instant5 = now.minusNanos(1);//减1纳秒
//判断
boolean after = now.isAfter(instant);//在前
boolean before = now.isBefore(instant);//在后
boolean equals = now.equals(instant);//相同

11.2.4 时间格式化DateTimeFormatter

格式化和解析写法:

//1.创建一个日期时间格式化器对象
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//2.格式化时间
LocalDateTime now1 = LocalDateTime.now();
ZonedDateTime now2 = ZonedDateTime.now();
//使用格式化器的format方法格式化(正向格式化)
String format1 = dtf.format(now1);
String format2 = dtf.format(now2);
System.out.println(format1);
System.out.println(format2);
//使用LocalDateTime,ZonedDateTime的format方法格式化(反向格式化)
String format3 = now1.format(dtf);
String format4 = now2.format(dtf);
System.out.println(format3);
System.out.println(format4);
//3.解析时间:解析时间一般使用LocalDateTime提供的解析方法来解析
String dateStr="2029-12-12 12:12:11";
LocalDateTime parse = LocalDateTime.parse(dateStr, dtf);
System.out.println(parse);

11.2.5 Period

可以用于计算两个 LocalDate 对象 相差的年数、月数、天数。

使用方法举例:

LocalDate start = LocalDate.of(2019, 1, 1);
LocalDate end = LocalDate.of(2019, 12, 31);
//1.创建Period对象,封装俩个日期对象
Period period = Period.between(start, end);
//2.通过Period对象获取俩个日期对象间隔的信息
int years = period.getYears();        
int months = period.getMonths();
int days = period.getDays();

11.2.6 Duration

可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;

  • 支持LocalTime
  • localDateTime
  • Instant

使用方法举例

LocalDateTime start = LocalDateTime.of(2020, 1, 1, 10, 10)
LocalDateTime end = LocalDateTime.of(2020, 1, 1, 10, 20);
//1.获取Duration对象
Duration duration = Duration.between(start, end);
//2.获取俩个时间对象间隔的信息
long days = duration.toDays();//间隔多少天
long hours = duration.toHours();//间隔多少小时
long minutes = duration.toMinutes();//间隔多少分钟
long millis = duration.toMillis();//间隔多少毫秒
long nanos = duration.toNanos();//间隔多少纳秒

十一,包装类

包装类就是基本数据类型对应的引用数据类型

本质就是用一个对象把数据包起来

基本数据类型对应的包装类
byteByte
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
  • 获取Integer对象的方式(了解即可,JDK5对此做了优化了)
方法名说明
public Integer(int value)根据传递的整数创建一个 Integer对象
public Intege(String s)根据传递的字符串创建一个Integer对象
public static Integer valueOf(int i)根据传递的整数创建一个Integer对象
public static Integer valueOf(String s)根据传递的字符串创建一个Integer对象
public static Integer valueOf(String s,int radix)根据传递的字符串和进制创建一个Integer对象

构造方法获取对象和静态方法获取对象的区别(掌握)

  1. 构造方法获取的对象地址值都是不同的

  2. 静态方法获取的对象

    在 Integer 对象中,会先创建好一个 Integer 数组,这个数组存储了 **-128~+127** 范围的数字

    如果传入 valueOf 的数据大小在这个范围之内,直接返回这个数组。

    如果不在这个范围才会 new Integer

  • 以前包装类进行计算的过程

    需求:把两个数据进行相加得到结果

    1. 把对象进行拆箱,变成基本数据类型(对象名.intValue())
    2. 相加
    3. 把得到的结果再次进行装箱(再变回包装类)
  • JDK5 之后新计算过程

    在 JDK5 的时候提出了一个机制 **,自动装箱和自动拆箱 **

    自动装箱:把基本数据类型自动变为对应的包装类

    自动拆箱:把包装类自动变为基本数据类型

Integer i1=10;//在底层会自动调用valueOf方法得到Integer对象,自动装箱!
int i2=i1;//自动拆箱
Integer i3=i1+i2;//jdk5的新计算方式
//

JDK5 之后可以把包装类和对应的基本数据类型当作一个东西了,因为他们会自动进行转化!

  • 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类型的整数
public XXX xxxValue(Integer i)将包装类转化为比如说short,byte,long等形式

转化类型只能为纯数字不能为字母

8 种包装类中,除了 Character 都有对应的 parseXXX 方法进行类型转化

十二,Arrays类

Arrays 是操作数组的工具类

常用方法

方法名说明
public static String toString(数组)把数组拼接成一个字符串
public static int binarySearch(数组,查找的元素)二分查找元素
public static int[] copyOf(原数组,新数组长度)拷贝数组(深拷)
public static int[] copyOfRange(原数组,起始索引,结束索引)拷贝数组(范围)(深拷)
public static void fill(数组,元素)填充数组
public static sort(数组)按照默认方式进行数组排序
public static sort(数组,排序规则)按照指定规则给数组排序

binarySearch 方法细节:

  1. 传入的数组内元素必须按照升序排序

  2. 如果查找的元素不存在就返回 - 插入点 -1

    插入点:比如说 1,2,4,5 查找 3,那么插入点就是 3

    此时返回 -3-1=-4

    减一的原因:如果此时我们要查找数字 0,那么此时如果返回的是 - 插入点,就会出现 -0 这种情况

copy 数组的底层就是 System.arrapCopy 这个方法执行的

copyOf 数组细节:

  1. 如果新数组长度小于拷贝数组,那么会部分拷贝

  2. 如果新数组长度等于拷贝数组,那么会完全拷贝

  3. 如果新数组的长度大于拷贝数组,那么多余部分会补上默认值

copyOfRange 细节:包头不包围,包左不包右,[0,1) 这个意思

sort 方法细节:

  1. 如果给基本数据类型排序,底层使用的是快速排序方法
  2. 默认升序排序

sort(数组名, 排序规) 方法细节:

  1. 只能给引用数据类型类型的数组排序
  2. 如果数组是基本数据类型需要转化为包装类
  3. 排序规则是一个接口,我们一般是用匿名内部类的方式进行编写
Integer[] arr={5,2,2,5,1,6,3};
Arrays.sort(arr,new Comparator<Integer>(){
    @Override
    public int compare(Integer 01,Integer o2){
        return o1-o2;//代表升序
    }
})
  1. sort 方法的底层原理,利用插入排序 + 二分查找方式进行排序

    默认把 0 索引的数据当作有序序列,1 索引到最后认为是无序的序列

    遍历无序序列得到里面的每一个元素,假设当前遍历得到元素 A

    把 A 往有序序列中进行插入,在插入的时候,利用二分查找确定 A 元素的插入点

    拿着 A 元素和插入点元素进行比较,比较规则就是 compare 方法的方法体

    1. 如果方法返回值>=0,拿着A继续和后面的元素比较
    2. 如果方法返回值<=,拿着A继续和前面的元素进行比较

    知道能确定 A 的最终位置

    compare 方法的形参:

    1. 参数 1:o1 表示在无序序列中,遍历得到的每一个元素

    2. 参数 2:o2 表示有序序列中的元素

    3. 返回值:

      负数:表示当前要插入的元素是小的,放在前面

      整数:表示当前要插入的元素是大的,要放在后面

      0:表示当前要插入的元素和现在的元素是一样大的,要放在后面

//sort排序演示
 以{2,3,1,5,6}为例
此时有序序列为2,无序序列为3,1,5,6
- 遍历无序序列得到3,此时o1=3,o2=2	o1-o2=3-2=1>0故3应该插入在2后面
此时形成了有序序列:2,3	无序序列:1,5,6
- 遍历无序序列得到1,此时o1=1,o2=3,o1-02=1-3=-2<0表式1应该插入到3的前面
再次遍历有序序列此时o1=1,o2=2	o1-o2=-1<0表示1应该插入到2的前面
此时形成了有序序列:1,2,3	无序序列:5,6
- 遍历无序序列得到5,此时o1=5,o2=3	5-3>0故5应该放到3的后面
此时形成有序序列:1,2,3,5	无序序列:6
- 遍历无序序列得到:6,此时o1=6,o2=5	o1-o2=6-5>0故6应该放在5的前面
此时有序序列为:1,2,3,5,6结束遍历!

十三,UUID类

13.1 什么是UUID?

UUID(Universally Unique Identifier)是全局唯一标识符,是一个 128 位的数字:

  • 16字节(128位)
  • 36个字符的字符串表示(8-4-4-4-12格式)
  • 示例:123e4567-e89b-12d3-a456-426614174000

13.2 UUID版本:

// 版本1:基于时间戳和MAC地址
UUID uuid1 = UUID.randomUUID();  // 通常是版本4

// 不同版本的区别:
UUID version1 = UUID.nameUUIDFromBytes("test".getBytes());  // 版本3
// 版本1: 时间戳 + MAC地址
// 版本3: MD5哈希命名空间
// 版本4: 随机生成(最常用)
// 版本5: SHA-1哈希命名空间

13.3 Java中的UUID类

核心方法:

import java.util.UUID;

// 1. 生成随机UUID(版本4 - 最常用)
UUID uuid = UUID.randomUUID();
String str = uuid.toString();  // "f47ac10b-58cc-4372-a567-0e02b2c3d479"

// 2. 从字符串解析
UUID parsed = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");

// 3. 基于名称生成(版本3/5)
UUID nameBased = UUID.nameUUIDFromBytes("example".getBytes());

// 4. 获取UUID的组成部分
long mostSigBits = uuid.getMostSignificantBits();  // 高64位
long leastSigBits = uuid.getLeastSignificantBits(); // 低64位

// 5. 比较和相等性
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.fromString(uuid1.toString());
boolean equal = uuid1.equals(uuid2);  // true