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
类(多态)那这里 也可以这样写 先判断
obj
与Student
是否存在父子关系 (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
这里可以看到 是先 实例化对象后 再进行转换 所以类型转换针对的是对象
-
装箱 :把 栈的基本类型 装到 堆里 转变成引用类型
-
拆箱 :把 堆里的引用类型 转变成 栈里的基本类型
-
> 注意 : 这里以上的 代码都是 JDK1.5 之前的 装箱拆箱方法 JDK1.5之后 Java提供了自动装箱跟自动拆箱
自动装箱:
int age = 30;
Integer integer = age;
无需再调用方法 直接等于 默认装箱
自动拆箱:
int age = integer;
基本类型和字符串之间的转换
-
基本类型转化为字符串
-
new Integer(n)
:首先创建了一个Integer
类的实例。 -
.toString()
:然后调用这个实例的toString
方法,返回封装的int
值的字符串表示。 -
创建一个新的
String
对象s1
,并将从Integer
实例得到的字符串赋值给它。
-
使用
+
号int i =150; String s1 = i+"";
-
使用
Integer
中的toString()
方法String s2 = Integer.toString(i);
这里 引用对象 不是
Integer
的情况下 也是直接使用了Integer
的方法原因:
toString()
是Integer
的一个静态方法 直接调用并将 i直接转变成 字符串 然后 赋值给 s2小拓展
toString()
的重载方法Integer.toString(int i ,int radix);
把
int i
当radix
进制返回String s2 = Integer.toString(i,16);//把 i 以 16 进制返回
-
实例化对象后 使用
toString()
方法区别于 第二种方法 这种方法
String s1 = new Integer(n).toString();
-
-
字符串转化为基本类型
String str = "150";
-
使用
Integer.parseXXX()
方法 是一个静态方法可以直接调用int n2 = Integer.parseInt(str);
这里要注意以下 如果 str 中存在不是 int 类型的字符
那么就会出现异常
Exception in thread "main" java.lang.NumberFormatException: For input string: "150c"
数字格式化异常
-
-
boolean :字符串 形式 转成 boolean 基本类型
注意 : 这里有点说法
-
如果 字符串为 "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
在内存中 应该是 这样子的 :
然后 我将 变量 name 改变一下
name = "罗锦源";
这时候 内存 会变成这样:
可以看到 原来的值
luojinyuan
并没有改变 而是新建了一个值而
luojinyuan
没有指向 利用System.gc()
就可以清理掉所以 可以看到 字符串不会改变 但变量可以改变 (重新建一个值)
-
字符串字面值存储在字符串池中 ,可以共享
这时候 我们再建一个变量
name2
等于罗锦源
内存又该如何?String name2 = "罗锦源";
这时候的内存应该是:
可以看到 在栈中 新建了一个 引用对象地址 并且在 常量池中 都指向相同的 对象
罗锦源
所以 并不会 在常量吃中 再新建一个字符串一模一样的常量 而是重新建了一个 引用地址
-
另外一种创建字符串的方式
String str1 = new String("str"); String str2 = new String("str");
这时候 栈中会产生相应的 地址 指向堆中的 新建对象 然后再指向常量池中的值
我们比较分两种方法比较一下
str1
和str2
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("[ ,]+");
-
equals
和compareTo
两种比较大小的方法首先 声明一点
两者的返回值不同
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();
-
append();追加字符
sb,append("java是 世界上最好的语言"); System.out.println(sb.toString());
-
insert();在某个位置添加字符
sb.insert(0,"你好 Java,");//在 下标0 的位置添加 System.out.println(sb.toString());
-
replace();替换
sb.replace(0,7,"Hello java"); System.out.println(sb.toString());
这里要注意 这里的区间是
[0,7)
含头不含尾 -
delete();删除
sb.delete(0,6); System.out.println(sb.toString());
这里要注意 这里的区间是
[0,6)
含头不含尾这里拓展一个 清空可变字符串的办法
sb.delete(0,sb.length()); System.out.println(sb.toString());
还是用
delete();
进行清空
-
效率比
String
高 -
比
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");
-
加法
add();
BigDecimal r1 = b1.add(b2); System.out.println(r1);
-
减法
subtract();
BigDecimal r2 = b1.subtract(b2); System.out.println(r2);
-
乘法
muliply();
BigDecimal r3 = b1.muliply(b2); System.out.println(r3);
-
除法
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
的意思是 四舍五入这样就不会报异常了
-
列式编程 连续运算
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年开始 到现在的毫秒数
方法
-
after();
和before();
判断时间的先后 返回值是布尔值boolean after = date.after(date1); System.out.println(after);
输出:
true
date
在date1
之后before();
同理 -
compareTo();
比较 时间减法 返回值是intint i = date.compareTo(date1); System.out.println(i);
输出:
1
-
equals();
比较是否相等 返回值是布尔值boolean equals = date.equals(date1); System.out.println(equals);
输出:
false
Calendar
-
Calendar 提供了获取或设置各种日历的方法
-
构造方法
protected Calendar();
注意这里的修饰符 是
protected
所以无法直接创建对象
方法
-
静态方法:
获取时间
Calendar calendar = Calendar.getInstance();
-
打印
我们先看使用
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
-
获取时间信息
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
-
修改时间
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
-
添加
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
-
获取时间的最大值 或 最小值 比如 一个月中的最后一天
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 |
- 实例化的时候 定义时间格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
- 然后定义一个 Date 类 试试
Date date = new Date();
- 格式化 Date 将日期变成字符串
format();
返回值是String类型
String format = sdf.format(date);
System.out.println(format);
输出:2024年06月03日 21:18:32
- 解析 将字符串转化为日期 返回值是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
-
系统类,主要用于获取系统的属性数据和其他操作,构造方法私有
-
大部分方法是 静态方法 所以不需要实例化 直接调用
方法
-
复制数组
static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
src
:原数组 要复制哪个数组srcPos
:从哪个位置开始复制 0dest
:目标数组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);
-
获取当前系统时间,返回毫秒值
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
是记录 运行结束后的一个时间差值就是用时
-
建议
JVM
赶快启动垃圾回收器回收垃圾static void gc();
这里具体看
Object
类中的finalize()
方法 -
退出
jvm
,如果参数是0
表示正常突出 非0
则是异常推出jvm
static void exit(int status);
退出Jvm虚拟机以后 后续的程序将不再运行
System.exit(0);