51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Java常用类的学习 (部分)

Java常用类

Object类

  • 基类 超类 所有类的直接或简介父类 位于继承树的最顶层

  • 任何类 ,如果没显示继承某个类 都默认继承 Object类

  • Object类中所定义的 方法 是所有对象都具备的方法

  • Object 类型可以储存任何对象

    • 作为参数,可以接受任何对象

    • 作为返回值,可以返回任何对象

getclass()方法

  • 后面加重将 class类型 反射的时候

  • 返回 一个 类型

  • 返回引用中储存的实际对象类型

  • 应用:通常用于判断两个引用棕实际储存对象类型是否一致

    public final class<?> getClass(){}
    

    代码方便理解

    用于判断两个引用棕实际储存对象类型是否一致

    先写了一个 Student 类

    public class Student{
        private String name;
        private int id;
        //构造方法
        public Student(String name,int id){
            this.name = name;
            this.id = id;
        }
        //get/set
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    }
    

    接下来是测试类 TestStudent

    public class TestStudent{
       public static void main(String[] args){
           Student s1 = new Student("a",18);
           Student s2 = new Student("b",20);
           //接下来就是使用 getClass 进行判断
           Class class1 = s1.getClass();
           Class class2 = s2.getClass();
           if(class1==class2){
               System.out.println("属于同一类型");
           }else
               System.out.println("不属于同一类型");
       }
    }
    

    为什么 可以判断

    **因为 getClass()方法 所返回的 是 Class类 是一个类 对实例对象类进行比较 **

    输出:

    属于同一类型
    

hashCode() 方法

  • 返回该对象的 哈希码值(int)

public int hashCode(){}
  • 根据对象的地址或者字符串或数字使用 hash算法计算出来的 int类型的数值

  • 一般情况下 相同对象返回相同哈希码

  • 可以判断两个对象是否是同一个

这里的类还是 使用上面的

public class TestStudent{
    public static void main(String[] args){
        Student s1 = new Student("a",18);
        Student s2 = new Student("b",20);
		Student s3 = s1;
        Student s4 = new Student("a",18);
        System.out.println("s1="+s1.hashCode());
        System.out.println("s2="+s2.hashCode());
        System.out.println("s3="+s3.hashCode());
        System.out.println("s4="+s4.hashCode());
    }
}

输出

s1=1163157884
s2=1956725890
s3=1163157884
s4=356573597

这里可以很清楚的看到 s3 的哈希码值 是与 s1相同的

但是 s4 的 与 s1的 不相同

因为 s3 是 直接 等于 s1的

但是 s4 虽然实际参数与 s1相同 但是 s4 是 类重新 new 出来的 一个对象 所以 地址是不一样的

toString()方法

public String toString(){}
  • 返回该对象的字符串表示对象 记住 是 直接 对对象进行打印的

  • 可以根据程序需求覆盖该方法 如:展示对象的各个属性值

  • 打印的是 带包的类的全名称@16进制的哈希值

    Inner.demo05.Student@4554617c
    Inner.demo05.Student@74a14482
    

    以上分别是 s1 和 s2 的

    4554617c 16进制 转化 10 进制就是 == 1163157884

    地址是一样的

    除了这个应用以外呢 还有可以根据需求 去重写 toString() 方法

    例如 还是调用Student类

    public class Student{
        private String name;
        private int id;
        //构造方法
        public Student(String name,int id){
            this.name = name;
            this.id = id;
        }
        public String toString(){
            return "Student{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    '}';
        }
    

    测试

    System.out.println(s1.toString());
    System.out.println(s2.toString());
    

    输出:

    Student{name='aaa', id=20}
    Student{name='bbb', id=18}
    

    可以看到改变了返回的方式

equals()方法

public boolean equals(Object obj){}
  • 默认实现是 (this == obj),比较两个 对象的 地址 注意 这里比较的是 地址

  • 可进行覆盖,比较两个对象内容是否相同

    hashCode() 方法中我们 了解到 即使 属性相同的 对象 地址也是不一样的 所以比较输出出来的 还是 false

    那我们是否可以 通过重写 equals 方法 来达到 两个类 属性相同 且 类也相同的 情况下 即使地址不同任然能输出 true

    开始思考 首先要达到 类 和 属性都相同 我们就要 设立if语句去判断类和属性

    if(this.getClass()==obj.getClass()){}
    

    在多态中我们学习到 父类可以指向子类 但是无法使用子类的方法

    那这里的 obj 编译类型其实是 Object 类 但是运行 则为 Student类(多态)

    那这里 也可以这样写 先判断 objStudent 是否存在父子关系 (instanceof

    if(obj instanceof Student){}
    

    还有一个需求 就是 让obj对象 与 Student 对象进行属性的比较

    使用的方法是 强制转换

    if(obj instanceof Student){
        Student s = (Student)obj;
        if(this.name.equals(s.name)&&this.id==s.id){
            return true
        }
    }
    return false;
    

    这里有个小疑问 后期解决

    为什么 变化后可以直接调用属性? 后面写代码验证一下

    这就写完了吗?

    还没有 这里还需要 满足以下 以前有的 一些内容

    比如 当 this对象 == obj 的时候 (地址也相同的情况)也应该输出 true

    obj ==null 的时候 应该输出为 false

    合起来一起写就是:

    public boolean equals(Object obj){
            if(this==obj){
                return true;
            }
            if(obj==null){
                return false;
            }
            //if(this.getClass()==obj.getClass()){
            if(obj instanceof Student){
                Student s = (Student)obj;//父类转子类的 强制转换
                //比较属性
                if(this.name.equals(s.name)&&this.id==s.id){
                    return true;
                }
            }
            return false;
        }
    

finalize() 方法 (Java9 开始被弃用)

  • 当对象被判定为 垃圾对象是 ,由 JVM 自动调用此方法 ,用以标记垃圾对象,进入回收队列

  • 垃圾对象:没有有效引用指向此对象 为 垃圾独享

  • 垃圾回收:由GC销毁垃圾对象啊你个 ,双方数据储存空间

  • 自动回收机制 :JVM内存耗尽,一次性回收所有垃圾对象

  • 手动回收机制:使用 System.gc();通知 JVM 执行垃圾回收

  • 回收没有被引用的对象

    重写finalize方法

    	@Override
        protected void finalize() throws Throwable {
            System.out.println(this.name+"对象被清理");
        }
    

    测试

    Student s1 = new Student("aaa", 20);
    Student s2 = new Student("bbb", 18);
    new Student("ccc",20);
    new Student("ddd",20);
    System.gc();
    System.out.println("回收完成");
    

    输出:

    回收完成
    ccc对象被清理
    ddd对象被清理
    

    可以看到 被引用的 s1 s2 并没有被回收

    但是 没有引用的 ccc ddd 被直接回收了

包装类

  • 栈里存的是 基本类型(没有方法) 堆里是引用类型

  • 为了让 基本类型可以使用方法 给 基本类型设计了所对应的引用数据类型 即为

    基本类型的包装类

  • 让基本类型 有属性 和 方法。

  • Object 可以统一 所有的数据 , 包装类 是引用类型 所以 默认值是 null

    | 基本数据类型 | 包装类型 | | ------------ | --------- | | byte | Byte | | short | Short | | int | Integer | | long | Long | | float | Float | | double | Double | | boolean | Boolean | | char | Character |

  • 装箱跟拆箱

    类型转换

    Number类

    `Byte、Integer、Long、Doublie、Short、Float 都是它的子类

    方法:

    拆箱方法:

    引用类型转化为基本类型

    | 返回值 | 方法名 | | --------------- | ------------- | | byte | byteValue () | | abstract double | doubleValue() | | abstract float | floatValue() | | abstract int | intValue() | | abstract long | longValue() | | short | shortValue() |

    装箱

    这以Integer为例

    | 返回值 | 方法名(静态方法) | | -------------- | ---------------- | | static Integer | valueOf(int i) |

    代码:

    public static void main(String[] args){
        int i = 18;
        //完成装箱 将 基本类型i 转变为 引用类型 integer
        Integer integer = Integer.valueOf(i);
    }
    

    这里有个疑问

    Integer.valueOf方法的返回值是一个类 这里相当于实例化了一个对象integer既然是 对象 那为什么输出的时候 打印出来不是 地址 而是具体的值? ai给出的答案是 : 当你打印integer时,实际上是调用了Integer类的toString()方法,该方法返回的是封装在Integer对象中的int值的字符串表示形式。

    使用 hashCode() 方法 再次输出一次 也是无法输出 出哈希值

    Integer类的hashCode()方法被覆盖,以返回封装的int值的哈希码,而不是对象本身的内存地址。

    拆箱

    代码

    Integer i3 = Integer.valueOf(i3);
    int i = i3.intValue();
    //成功将 引用类型 Integer 转变为 基本类型 i
    

    这里可以看到 是先 实例化对象后 再进行转换 所以类型转换针对的是对象

    1. 装箱 :把 栈的基本类型 装到 堆里 转变成引用类型

    2. 拆箱 :把 堆里的引用类型 转变成 栈里的基本类型

> 注意 : 这里以上的 代码都是 JDK1.5 之前的 装箱拆箱方法 JDK1.5之后 Java提供了自动装箱跟自动拆箱

自动装箱:

int age = 30;
Integer integer = age;

无需再调用方法 直接等于 默认装箱

自动拆箱:

int age = integer;

基本类型和字符串之间的转换

  • 基本类型转化为字符串

    1. new Integer(n):首先创建了一个 Integer 类的实例。

    2. .toString():然后调用这个实例的 toString 方法,返回封装的 int 值的字符串表示。

    3. 创建一个新的 String 对象 s1,并将从 Integer 实例得到的字符串赋值给它。

    1. 使用 +

      int i =150;
      String s1 = i+"";
      
    2. 使用 Integer 中的 toString()方法

      String s2 = Integer.toString(i);
      

      这里 引用对象 不是Integer的情况下 也是直接使用了 Integer的方法

      原因:toString()Integer的一个静态方法 直接调用并将 i直接转变成 字符串 然后 赋值给 s2

      小拓展 toString()的重载方法

      Integer.toString(int i ,int radix);

      int iradix 进制返回

      String s2 = Integer.toString(i,16);//把 i 以 16 进制返回
      
    3. 实例化对象后 使用 toString()方法

      区别于 第二种方法 这种方法

      String s1 = new Integer(n).toString();
      
  • 字符串转化为基本类型

    String str = "150";
    
    1. 使用 Integer.parseXXX()方法 是一个静态方法可以直接调用

      int n2 = Integer.parseInt(str);
      

      这里要注意以下 如果 str 中存在不是 int 类型的字符

      那么就会出现异常

      Exception in thread "main" java.lang.NumberFormatException: For input string: "150c"
      

      数字格式化异常

  • boolean :字符串 形式 转成 boolean 基本类型

    注意 : 这里有点说法

    1. 如果 字符串为 "true" 那么 就是 true 如果不是 "true" 就都是 "false"

      String str = "true";
      boolean b1 = Boolean.parseBoolean(str);
      System.out.println(b1);
      
      true
      
      String str = "1";
      boolean b1 = Boolean.parseBoolean(str);
      System.out.println(b1);
      
      false
      

整数缓冲区

  • Java预先创建了 256 个常用的整数包装类型对象

  • 再实际应用当中 对已创建的对象进行复用

在了解 整数缓冲区 之前 我们需要重新看一下 自动装箱的 class文件

在 class 文件中 很清楚的看到

自动装箱 是通过 Integer.valueOf() 静态方法 来实现的

Integer integer = 100;
// Integer integer = Integer.valueOf(100);

那么什么是整数缓冲区 ?

我们通过一个问题进行引入

Integer integer3 = Integer.valueOf(100);
Integer integer4 = Integer.valueOf(100);
System.out.println(integer3==integer4);//true ?

Integer integer5 = Integer.valueOf(200);
Integer integer6 = Integer.valueOf(200);
System.out.println(integer5==integer6);//false ?

在这里 当int i = 100 的时候比较相同 输出的是 true

int i = 200 的时候比较相同 输出的是 false

为什么?

我们通过查看 valueOf() 方法的源码 了解到

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= 			IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

IntegerCache.low = -128;

IntegerCache.high = 127;

IntegerCache.cache[(high - low)+1];

i >= -128 && i <= 127时 返回值 是一个 数组内的元素 即为 int 类型

除非 就是返回一个 对象 这时候输出的 就是一个 地址

所以当 i = 200时 对比才会 输出 false.

而 这个 [-128 , 127] 的区间 就是 整数缓冲区

在 区间内返回 int 类型的 值

在 区间外 返回 对象

String类

  • 字符串是常量 , 创建之后不可以改变

    这里的不可改变的意思是:

    比如 我现在写了一行代码

    String name = "luojinyuan";
    

    这里定义了一个String类变量 name

    在内存中 应该是 这样子的 :

    image-20240530215437700

    然后 我将 变量 name 改变一下

    name = "罗锦源";
    

    这时候 内存 会变成这样:

    image-20240530215547135

    可以看到 原来的值 luojinyuan 并没有改变 而是新建了一个值

    luojinyuan没有指向 利用 System.gc()就可以清理掉

    所以 可以看到 字符串不会改变 但变量可以改变 (重新建一个值)

  • 字符串字面值存储在字符串池中 ,可以共享

    这时候 我们再建一个变量name2等于 罗锦源 内存又该如何?

    String name2 = "罗锦源";
    

    这时候的内存应该是:

    image-20240530220125255

    可以看到 在栈中 新建了一个 引用对象地址 并且在 常量池中 都指向相同的 对象 罗锦源

    所以 并不会 在常量吃中 再新建一个字符串一模一样的常量 而是重新建了一个 引用地址

  • 另外一种创建字符串的方式

    String str1 = new String("str");
    String str2 = new String("str");
    

    这时候 栈中会产生相应的 地址 指向堆中的 新建对象 然后再指向常量池中的值

    image-20240530221537995

    我们比较分两种方法比较一下 str1str2

    System.out.println(str1 == str2);
    System.out.println(str1.equals(str2));
    

    输出:

    false
    true
    

    首先说说为什么 输出 是 false

    因为 用 ==比较对象时 比较的是 对象地址 再内存图中 可以清楚的看到 新建了 两个对象分别表示 str1 str2

    所以输出 false

    那为什么用 equals方法输出就是 true

    因为 再 String类中 equals被重写了 比较的是 字符串是否相同

常用方法

  • 返回 字符串的长度

    public int length();
    

    使用:

    String name = "java是世界上最好的语言java ";
    System.out.println(name.length());
    
  • 根据下标获取字符

    public char charAt(int index);
    

    使用:

    System.out.println(name.charAt(3));
    System.out.println(name.charAt(name.length()-1));
    

    注意防止下标越界

  • 判断是否包含某个字符

    public boolean contains(String str);
    

    输出:

    System.out.println(name.contains("是"));
    
  • 将字符串转化为数组

    public char[] toCharArray();
    

    使用:

    char[] a = name.toCharArray();
    System.out.println(Arrays.toString(a));
    
  • 查找 str 首次出现的下标

    存在 , 返回该下标

    不存在 ,返回 -1

    public int indexOf(String str);
    

    使用:

    System.out.println(name.indexOf("java"))
    

    输出:0 输出 是首个字符的位置

    拓展:

    从 第 index 个数开始 查找str

    public int indexOf(String str,int index);
    

    使用:

    System.out.println(name.indexOf("java",4))
    

    输出:13

    > 从第四个开始查找 java 找到后 在字符下标 13的位置

  • 查找字符串再当前字符中最后一次出现的下标索引

    public int lastIndexOf(String str);
    

    使用:

    System.out.println(name.lastIndexOf("java"));
    

    输出:13

  • 去掉字符串前后的空格

    public String trim();
    

    使用:

    String name2 = name.trim();
    System.out.println(name2);
    

    输出:java是世界上最好的语言java

    这里要注意 输出出来的 是字符串

  • 将小写转成大写

    public String toUpperCase();
    

    使用:

    String name3 = "hello,World";
    System.out.println(name3.toUpperCase());
    

    输出:HELLO,WORLD

  • 判断字符串是否以 str 结尾(开头)

    public boolean endWith(String str);//结尾
    public boolean startWith(String str);//开头
    

    使用:

    System.out.println(name3.endWith("World"));
    public boolean startWith("Hello")
    

输出:true true

  • 将旧字符串替换为新字符串

    public String replace(char oldChar,char newChar);
    

    使用:有一个接口的形参 可以直接用字符串 不只是用字符

    name.replace("Java","php").sout
    

    输出:php是世界上最好的语言php

  • 根据str做拆分

    public String[] split(String str);
    

    使用

    String say = "java is te best propraming language,java xiang";
    String[] s = say.spilt(" ");
    Arrays.toString(s).sout
    

    输出:[java, is, te, best, propraming, language,java, xiang]

    拓展

    比如 可以看到 上面的 s替换的时候 ,跟前面的连在一起了 我想将,也隔开

    可以这样写

    String[] s = say.spilt("[ ,]");
    

    []里面写入 一个空格和 , 意思是 遇到 空格 或 ,的时候 进行拆分

    如果是 双空格也拆分的话

    可以在 []后面 加上 一个 +

    String[] s = say.spilt("[ ,]+");
    
  • equalscompareTo 两种比较大小的方法

    首先 声明一点

    两者的返回值不同

    equals 的返回值是 boolean

    compareTo 的返回值是 int

    String s1 = "hello";
    String s2 = "HELLO";
    System.out.println(s1.equalsIgnoreCase(s2));
    

    equalsIgnoreCase() 这个方法 可以让 equlas在比较的时候忽略大小写

    String s3 = "abc";
    String s4 = "xyz";
    String s5 = "abcxyz";
    System.out.println(s3.compareTo(s4));
    

    这个代码其实是 做减法

    s3 首字母在 字符表中的 位置 比如 上面代码中 的 a 97

    减去

    s4 首字母在 字符表中的 位置 比如 上面代码中 的 x 120

    输出 :-23

    加入 首字母相同 那么 就比较下一位 以此类推

    特殊情况:

    System.out.println(s3.compareTo(s5));
    

    这里 前面都一样 但是 s3 没有了 s5 还有

    这里 就不比较 在 字符表中的 值了

    这里比较 长度

    所以输出的是 3-6

    输出:-3

    • compareTo

    • equals

  • 截取字符

    public String substring(int beginIndex,int endIndex)
    

    针对 字符串截取字符

    String name = "luojinyuan";
    name.substring(1);
    

    从下标是 1 的字符开始截取字符串到最后

    省略了后面的参数 endIndex 的意思是 截取到 最后一个的字符下标 可以自定义截取 默认为最后一个

    输出:uojinyuan

  • 可变长字符串

    这两是 类 不是方法

    StringBuffer:可变长字符串,JDK1.0提供,相对StringBuffer运行效率慢,线程安全

    StringBuilder:可变长字符串,JDK5.0提供,运行效率块,线程不安全,单线程建议用这个

    这两个类 与 String 的区别

    代码验证运行效率

    String

    long start = System.currentTimeMillis();
    String string = "";
    for (int i = 0; i < 99999; i++) {
    	string+=i;
    }
    System.out.println(string);
    long end = System.currentTimeMillis();
    System.out.println("用时"+(end-start));
    

    输出:用时20272

    StringBuffer

    long start = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < 99999; i++) {
    	stringBuffer.append(i);
    }
    System.out.println(stringBuffer);
    long end = System.currentTimeMillis();
    System.out.println("用时"+(end-start));
    

    输出:用时16

    使用方法

    首先 使用类的方法 先 实例化类

    StringBuffer sb = new StringBuffer();
    
    1. append();追加字符

      sb,append("java是 世界上最好的语言");
      System.out.println(sb.toString());
      
    2. insert();在某个位置添加字符

      sb.insert(0,"你好 Java,");//在 下标0 的位置添加
      System.out.println(sb.toString());
      
    3. replace();替换

      sb.replace(0,7,"Hello java");
      System.out.println(sb.toString());
      

      这里要注意 这里的区间是 [0,7) 含头不含尾

    4. delete();删除

      sb.delete(0,6);
      System.out.println(sb.toString());
      

      这里要注意 这里的区间是 [0,6) 含头不含尾

      这里拓展一个 清空可变字符串的办法

      sb.delete(0,sb.length());
      System.out.println(sb.toString());
      

      还是用 delete(); 进行清空

    1. 效率比 String

    2. String 节省内存

BigDecimal

引入:

public static void main(String[] args) {
        double d1 = 1.0 ;
        double d2 = 0.9 ;
        System.out.println(d1-d2);
    }
}

输出:0.09999999999999998

不等于 0.1

因为 double 有精度问题 存储的值不一定是 1.0 可能是 0.99999999999

这里引入一个 类

BigDecimal 可以对浮点数进行精准的运算

前面也说过 这个类用于 银行等地方的运算

方法

浮点数的运算

还是那句话 使用类前 先 实例化

BigDecimal b1 = new BigDecima("1.0");//这里注意以下 要用字符串 字符串最为精确
BigDecimal b2 = new BigDecima("0.9");
  1. 加法add();

    BigDecimal r1 = b1.add(b2);
    System.out.println(r1);
    
  2. 减法subtract();

    BigDecimal r2 = b1.subtract(b2);
    System.out.println(r2);
    
  3. 乘法muliply();

    BigDecimal r3 = b1.muliply(b2);
    System.out.println(r3);
    
  4. 除法divide(); 注意以下异常

    BigDecimal r3 = b1.muliply(b2);
    System.out.println(r3);
    

    这是 1.0/0.9 是除不尽的 会报异常

    Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    

    这里很好解决 就是 divide(); 这个方法中 有一个 精确到小数的参数

    public BigDecimal divide(BigDecimal bd,int scal,RoundingMode mode){}
    

    scal:指定精确到小数点后几位

    mode:指定小数部分的取舍模式,经常采用四舍五入 如下

    BigDecimal divide = b1.divide(b2,2,BigDecimal.ROUND_HALF_UP);
    

    这里的意思是 b1/b2 精确到小数点后两位 ,BigDecimal.ROUND_HALF_UP 的意思是 四舍五入

    这样就不会报异常了

  5. 列式编程 连续运算

    BigDecimal r2 = new BigDecimal("1.0")
             		.subtract(new BigDecimal("35"))
             		.add(new BigDecimal("65"))
             		.multiply(new BigDecimal("59"))
             		.divide(new BigDecimal("11"),2,BigDecimal.ROUND_HALF_UP);
    System.out.println(r2);
    

    输出:166.27

Date

  • Date表示 瞬间 精确到毫秒

  • 现在大部分的方法 都被 Calendar

  • 不太全面,国际化问题 所以被取代

构造方法 无参:

public Date();

创建一个 Date对象 当前的时间 精确到毫秒

打印

 Date date1 = new Date();
 System.out.println(date1);

直接打印的话 格式 是这样的

输出:Mon Jun 03 20:31:04 CST 2024

所以一般用这个方法来打印toLocalString();

System.out.println(date1.toLocaleString());

不过呢 这个方法已经过时了但是仍然可以使用

上面的是 今天 的 写一个昨天的此时此刻

Date date2 = new Date(date.getTime()-(24*60*60*1000));
System.out.println(date2.toLocaleString());

> getTime();返回的是 从 1970年开始 到现在的毫秒数

方法

  1. after();before(); 判断时间的先后 返回值是布尔值

    boolean after = date.after(date1);
    System.out.println(after);
    

    输出:true

    datedate1 之后

    before();同理

  2. compareTo(); 比较 时间减法 返回值是int

     int i = date.compareTo(date1);
     System.out.println(i);
    

    输出:1

  3. equals(); 比较是否相等 返回值是布尔值

    boolean equals = date.equals(date1);
    System.out.println(equals);
    

    输出:false

Calendar

  • Calendar 提供了获取或设置各种日历的方法

  • 构造方法

    protected Calendar();
    

    注意这里的修饰符 是protected所以无法直接创建对象

方法

  1. 静态方法:

    获取时间

    Calendar calendar = Calendar.getInstance();
    
  2. 打印

    我们先看使用 toString();方法打印

    System.out.println(calendar);
    

    输出:

    java.util.GregorianCalendar[time=1717418897886,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=5,WEEK_OF_YEAR=23,WEEK_OF_MONTH=2,DAY_OF_MONTH=3,DAY_OF_YEAR=155,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=48,SECOND=17,MILLISECOND=886,ZONE_OFFSET=28800000,DST_OFFSET=0]

    看不懂

    所以不能直接输出

    那我们如何打印

    我们先 使用 getTime(); 方法 将它变成Date再使用 toLocalString(); 方法进行打印

    System.out.println(calendar.getTime().toLocalString());
    

    输出:2024-6-3 20:48:17

    还有一种 是 打印毫秒值

    System.out.println(calendar.;getTimeInMillis());
    

    输出:1717418897886

  3. 获取时间信息 get();

    在 Calendar 类中 提供了很多常量

    YEAR MONDAY MONDAY

    int i = calendar.get(Calendar.YEAR);
    int i1 = calendar.get(Calendar.MONDAY);
    int i2 = calendar.get(Calendar.MONDAY);
    int i3 = calendar.get(Calendar.HOUR_OF_DAY);
    int i4 = calendar.get(Calendar.MINUTE);
    int i5 = calendar.get(Calendar.SECOND);
    System.out.println(i+"年"+(i1+1)+"月"+i2+"日"+i3+":"+i4+":"+i5);
    

    输出:2024年6月3日20:48:17

    这里有个点 就是 在 HOUR中 有两个

    HOUR:12小时

    HOUR_OF_DAY:24小时

    还有就是

    可以看到 MOUTH 月中 是从 0 开始的

    所以要+1

  4. 修改时间 set();

    Calendar calendar1 = Calendar.getInstance();
    calendar1.set(Calendar.DAY_OF_MONTH,5);
    System.out.println(calendar1.getTime().toLocaleString());
    

    输出:2024-6-5 20:59:41

    这里是直接 将 Calendar.DAY_OF_MONTH 改成了 5

  5. 添加 add();

    calendar1.add(Calendar.HOUR_OF_DAY,1);
    System.out.println(calendar1.getTime().toLocaleString());
    

    输出:2024-6-5 21:59:41

    这里是将Calendar.HOUR_OF_DAY 增加了 1

  6. 获取时间的最大值 或 最小值 比如 一个月中的最后一天 getActualMaximum(); getActualMinimum();

    int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    System.out.println(actualMaximum);
    

    输出:30

SimpleDateFormat

  • 以语言环境有关的方式格式化和解析日期的具体类

  • 进行格式化(日期---->文本)

  • 解析(文本---->日期)

  • 常用时间模式字母

| 字母 | 日期或时间 | 实例 | | ---- | ------------------- | ---- | | y | 年 | 2019 | | M | 年中月份 | 08 | | d | 月中天数 | 10 | | H | 1天中小时数(0-23) | 22 | | m | 分钟 | 16 | | s | 秒 | 59 | | S | 毫秒 | 367 |

  1. 实例化的时候 定义时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
  1. 然后定义一个 Date 类 试试
Date date = new Date();
  1. 格式化 Date 将日期变成字符串 format(); 返回值是String类型
String format = sdf.format(date);
System.out.println(format);

输出:2024年06月03日 21:18:32

  1. 解析 将字符串转化为日期 返回值是Date类型
Date parse =sdf.parse("2024年06月03日 20:10:06");
System.out.println(parse.toLocaleString());

输出:2024-6-3 20:10:06

如果 这里输入的字符串不是 上面 sdf 所定义的格式 就会异常

解析失败异常

Exception in thread "main" java.text.ParseException: Unparseable date: "202406月03日 20:10:06"

System

  • 系统类,主要用于获取系统的属性数据和其他操作,构造方法私有

  • 大部分方法是 静态方法 所以不需要实例化 直接调用

方法

  1. 复制数组

    static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
    

    src:原数组 要复制哪个数组

    srcPos:从哪个位置开始复制 0

    dest:目标数组

    destPos:目标数组的位置 从哪里开始放复制的东西

    length:复制的长度

    int[] arr ={20,18,15,8,35,26,45,30};
    int[] dest = new int[arr.length];
    System.arraycopy(arr,0,dest,0,arr.length);
    
  2. 获取当前系统时间,返回毫秒值

    static long currentTimeMillis();
    

    之前在 可变长字符串里面使用过这个来测试运行的时间

    long start = System.currentTimeMillis();
    String string = "";
    for (int i = 0; i < 99999; i++) {
        string+=i;
    }
    System.out.println(string);
    long end = System.currentTimeMillis();
    System.out.println("用时"+(end-start));
    

    start是记录 还未运行下面程序时 的一个 时间

    end 是记录 运行结束后的一个时间

    差值就是用时

  3. 建议JVM赶快启动垃圾回收器回收垃圾

    static void gc();
    

    这里具体看 Object类中的 finalize()方法

  4. 退出jvm,如果参数是 0 表示正常突出 非0则是异常推出 jvm

    static void exit(int status);
    

    退出Jvm虚拟机以后 后续的程序将不再运行

    System.exit(0);
    
赞(1)
未经允许不得转载:工具盒子 » Java常用类的学习 (部分)