Java笔记——常用类

包装类 Wrapper

包装类的分类

  1. 针对八种基本数据类型相应的引用类型——包装类
  2. 有了类的特点,就可以调用类中的方法
基本数据类型 包装类
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

前两种包装类,实现 ComparableSerializable 接口

后六种包装类的父类为 Number, 这些包装类自身实现 Comparable 接口, Number 实现 Serializable 接口

包装类和基本数据类型的转换

  1. jdk5前的手动装箱和拆箱方式,装箱:基本类型 \(\rightarrow\) 包装类型,反之,拆箱
  2. jdk5以后(含jdk5)的自动装箱和拆箱方式
  3. 自动装箱底层调用的是 valueOf 方法,比如 Integer.valueOf()
1
2
3
4
5
6
7
8
9
10
// 手动装箱和拆箱
int n1 = 100;
Integer integer = new Integer(n1); // 装箱1
Integer integer1 = Integer.valueOf(n1); // 装箱2
int n = integer.intValue(); // 拆箱

// 自动
int n2 = 200;
Integer integer2 = n2;
int n = integer2;

exercise

1
2
Object obj1 = true ? new Integer(1) : new Double(2.0);
System.out.println(obj1); // 1.0

三元运算符看作一个整体,提升精度

包装类型和 String 类型的相互转换

IntegerString 转换为例,其它类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 包装类型 -> String类型
Integer i = 10;
// 方式1
String s1 = i.toString();
// 方式2
String s2 = String.valueOf(i);
// 方式3
String s3 = i + "";

// String 类型 -> 包转类型
// 方式1
Integer j = new Integer(s1);
// 方式2
Integer j2 = Integer.valueOf(s2);

// int类型 -> String类型 (效率从高到低)
Integer.toString(int i);
String.valueOf(int i);
i + "";

Integer 类和 Character 类的常用方法

1
2
3
4
5
6
7
8
9
10
11
12
Integer.MIN_VALUE  // 返回最小值
Integer.MAX_VALUE // 返回最大值

Character.isDigit('a') // 判断是不是数字
Character.isLetter('a') // 判断是不是字母
Character.isUpperCase('a'); // 判断是不是大写
Character.isLowerCase('a'); // 判断是不是小写

Character.isWhitespace('a'); // 判断是不是空格
Character.toUpperCase('a') // 转成大写
Character.toLowerCase('A') // 转成小写

exercise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void method() {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); // false

Integer m = 1; // 自动装箱 Integer.valueOf(1);
Integer n = 1;
System.out.println(m == n); // true

Integer x = 128;
Integer y = 128;
System.out.println(x == y); // false
}

// valueOf() 看范围, -128~127就直接返回,否则new Integer对象
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) // low = -128, high = 127
return IntegerCache.cache[i + (-IntegerCache.low)]; // 缓存数组 0 ~ 255
return new Integer(i);
}
1
2
3
4
5
6
7
8
Integer x = 127;
int y = 127;
System.out.println(x == y); // true

// 只要有基本数据类型,则判断值是否相等!
Integer m = 128;
int n = 128;
System.out.println(m == n); // true

String 类

1
2
3
4
5
6
7
8
9
10
11
// 源码 节选
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
// 实现Serializable接口, 说明String可以串行化,网络传输
// 实现Comparable接口,说明String对象可以比较

@Stable
private final byte[] value;
// ...
}

String 类的理解和创建对象

  1. String 对象用于保存字符串,也就是一组字符序列;
  2. 字符串常量对象是用双引号括起的字符序列,例如:"你好""12.97""girl"
  3. 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节;
  4. String 类较常用构造器:
1
2
3
4
5
String s1 = new String();
String s2 = new String(String original);
String s3 = new String(char[] a);
String s4 = new String(char[] a, int startIndex, int count);
String s5 = new String(byte[] b);
  1. String 类实现了Serializable接口,和Comparable接口, 作用见上边注释;
  2. Stringfinal 类,不能被其他的类继承
  3. String 有属性 private final byte[] value; 用于存放字符串内容(jdk8及以前是char),value 是一个 final 类型,地址不可修改,即value不可指向新的地址,但是单个字符内容是可以修改的。

创建 String 对象的两种方式

1
2
3
4
5
// 方式一:直接赋值
String s = "hello";

// 方式二:调用构造器
String s = new String("hello");
  • 两种创建 String 对象的区别:
    • 方法一:先从常量池查看是否有"hello"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向常量池的空间地址;
    • 方式二:先从堆中创建空间,里面维护了value属性,指向常量池的"hello"空间。如果常量池没有"hello",重新创建,如果有,直接通过value指向。s最终指向的是堆中的空间地址;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// exercise 1
String a = "abc";
String b = "abc";
System.out.println(a.equals(b)); // T String的equals被重写过
System.out.println(a == b); // T 内存中指向同一地址

// exercise 2
String a = new String("abc");
String b = new String("abc");
System.out.println(a.equals(b)); // T String的equals被重写过
System.out.println(a == b); // F 内存中指向不同地址

// exercise 3
String a = "xyz";
String b = new String("xyz");
System.out.println(a == "xyz"); // T
System.out.println(a == b.intern()); // T b.intern()返回常量池的地址(对象)
System.out.println(b == b.intern()); // F 堆地址 != 常量池地址

当调用intern方法时,如果池已经包含一个等于此 String 对象的字符串 (用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。 #### exercise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Animal {
String name;
public Animal(String name) {
this.name = name;
}
}

String s1 = "java"; // 栈 -> 常量池1
Animal a = new Animal(s1); // 栈 -> 堆1 -> 常量池1
Animal b = new Animal(s1); // 栈 -> 堆2 -> 常量池1
System.out.println(a == b); // F a和b指向不同对象
System.out.println(a.equals(b)); // F Animal类的equals没有被重写, equals仍然判断a和b是否是同一个对象
System.out.println(a.name == b.name); // T a.name和b.name指向同一对象

String s4 = new String("java"); // 栈 -> 堆(value) -> 常量池1
String s5 = "java"; // 栈 -> 常量池1
System.out.println(s1 == s4); // F
System.out.println(s4 == s5); // F

String t1 = "hello" + s1; // 引用拼接会调用new String 栈 -> 堆(value) -> 常量池2
String t2 = "hellojava"; // 栈 -> 常量池2
System.out.println(t1.intern() == t2); // T .intern()指向常量池

字符串对象的特性

  1. String 是一个 final 类,代表不可变的字符序列
  2. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。

exercise

1)以下语句创建了几个对象?

1
2
3
String s1 = "hello";
s1 = "hhh";
// 常量池创建了两个对象 s1先指向"hello", 后指向"hhh",而非直接修改"hello"

2)

1
2
3
String a = "hello" + "abc";
// 创建一个对象,编译器优化 判断创建的常量池对象,是否有引用指向
// 上述语句等价于 String a = "helloabc";

3)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String a = "hello";  // 创建a对象
String b = "abc"; // 创建b对象
String c = a + b; // c指向堆,堆指向常量池
// 创建三个String对象
/**jdk8
1. 先创建一个 StringBuilder 对象 sb
2. 执行 sb.append("hello");
3. 执行sb.append("abc");
4. 执行 String c = sb.toString(); // toString()里执行new String()
*/

// 验证
String d = "hello" + "abc";
System.out.println(c == d); // false

4)

1
2
3
4
5
6
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = (s1 + s2).intern();
System.out.println(s3 == s4); // true
System.out.println(s3.equals(s4)); // true

5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test1 {
String str = new String("hello");
final char[] ch = {'j', 'a', 'v', 'a'};
public void change(String str, char ch[]) {
str = "java";
ch[0] = 'h';
}

public static void main(String[] args) {
Test1 ex = new Test1();
ex.change(ex.str, ex.ch);
System.out.print(ex.str + " and "); // "hello and "
System.out.println(ex.ch); // hava
}
}

String 类的常见方法

String 类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此Java设计者还提供了 StringBuilderStringBuffer 来增强 String 的功能,并且提高效率。

1
2
3
4
String s = new String("");
for (int i = 0; i < 80000; i ++ ) {
s += "hello"; // 拼接 每次都要常量池开辟空间
}
  • 常见方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
equals // 判断内容是否相等
equalsIgnoreCase // 忽略大小写判断内容是否相等
length // 获取字符个数,即字符串的长度
indexOf // 获取字符在字符串中第一次出现的索引,索引从0开始,如果找不到则返回 -1
lastIndexOf // 获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到则返回 -1
substring // 截取指定范围的子串
trim // 去掉前后空格
charAt // 获取某索引处的字符,注意String str = "hello",不可使用str[idx]; 正确用法str.chatAt(idx)

toUpperCase // 转成大写
toLowerCase // 转成小写
concat // 拼接
replace // 代替字符串中的字符, 注意:返回的对象被替换,原字符串没变!
split // 分割字符串,对于某些字符需要转义
compareTo // 比较两个字符串的大小
toCharArray // 转成字符数组
format // 格式化字符串, 占位符 %s字符串 %c字符 %d整数 %.2f浮点数

exercise 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.company.string_;

/**
* @author nessaj
* @date 2022/6/21 21:53
*/
public class StringExercise {
public static void main(String[] args) {
String str = "abcdef";

try {
str = reverse(str, 0, 5); // 要接收
} catch (RuntimeException e) {
System.out.println(e.getMessage());
return;
}
System.out.println("交换后: " + str);

}
public static String reverse(String str, int start, int end) {
if (!(str != null && start >= 0 && end < str.length() && start < end)) {
throw new RuntimeException("参数不正确");
}

char[] chars = str.toCharArray(); // String不可交换,先转成char[]
char tmp;
for (int i = start, j = end; i < j; i++, j--) {
tmp = chars[i];
chars[i] = chars[j];
chars[j] = tmp;
}
return new String(chars);
// return String.valueOf(chars);
}
}

exercise 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.company.string_;

/**
* @author nessaj
* @date 2022/6/22 10:38
*/
public class StringExercise02 {
public static void main(String[] args) {
String name = "kuhn";
String pwd = "123445";
String email = "c_kudos@163.com";
try {
userRegister(name, pwd, email);
System.out.println("正常运行...");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}

// 校验信息是否异常
public static void userRegister(String name, String pwd, String email) {
if (!(name != null && pwd != null && email != null)) {
throw new RuntimeException("参数不能为空");
}
int len = name.length();
if (!(len >= 2 && len <= 4)) {
throw new RuntimeException("用户名长度2~4");
}
if (!(pwd.length() >= 6 && isDigital(pwd))) {
throw new RuntimeException("密码长度大于等于6,且全为数字");
}
int idx1 = email.indexOf('@');
int idx2 = email.indexOf('.');
if (!(idx1 > 0 && idx2 > idx1)) {
throw new RuntimeException("邮箱不合规范");
}
}

public static boolean isDigital(String str) {
char[] chars = str.toCharArray();
for (char aChar : chars) {
if (aChar < '0' || aChar > '9')
return false;
}
return true;
}
}

StringBuffer 类

java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删;很多方法与 String 相同,但 StringBuffer 是可变长度的; StringBuffer 是一个容器。

在父类中, AbstractStringBuilder 有属性 byte[] value,不是 final,该 value 数组存放字符内容,存放在堆中而非常量池中。

StringBuffer 是一个 final 类,不能被继承。

String VS StringBuffer

  1. String 保存的是字符串常量,里面的值不能更改,每次 String 类的更新实际上就是更改地址,效率较低

    private final byte value[];

  2. StringBuffer 保存的是字符串变量,里面的值可以更改,每次 StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高

    byte[] value; //这个放在堆中

StringBuffer 的构造器

1
2
3
4
5
6
7
8
StringBuffer() // 构造一个不带字符的字符串缓冲区,其初始容量为16个字符

StringBuffer(CharSequence seq) // 构造一个字符串缓冲区,包含与指定的CharSequence相同的字符

StringBuffer(int capacity) // 构造一个不带字符, 但具有指定初始容量的字符串缓冲区,即对 char[]/byte[] 大小进行指定

StringBuffer(String str) // 构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容
// str.length + 16

String 和 StringBuffer 相互转换

1
2
3
4
5
6
7
8
9
10
11
12
13
// String -> StringBuffer
String s = "hello";
// 方式1
StringBuffer b1 = new StringBuffer(s);
// 方式2
StringBuffer b2 = new StringBuffer();
b2.append(s);

// StringBuffer -> String
// 方式1
String s2 = b1.toString();
// 方式2
String s3 = new String(b1);

StringBuffer 类的常见方法

1
2
3
4
5
6
1. 增 append
2.delete(start, end)
3.replace(start, end, string) // 前开后闭
4. 查 indexOf // 返回索引位置
5. 插 insert
6. 获取长度 length()

Exercise

1
2
3
4
5
6
7
8
9
String str = null;
StringBuffer sb = new StringBuffer();
sb.append(str); // 查看源码,底层调用AbstractStringBuilder的appendNull
System.out.println(sb.length()); // 4

System.out.println(sb); // "null"
// 下面构造器会抛出空指针异常
StringBuffer sb1 = new StringBuffer(str); // 查看源码, super(str.length() + 16);
System.out.println(sb1);
1
2
3
4
5
6
String price = "8123456.59";
StringBuffer sb = new StringBuffer(price);
for (int i = sb.LastIndexOf(".") - 3; i > 0; i -= 3) { // 先减3再判断插入
sb = sb.insert(i, ",");
}
System.out.println(sb); // 8,123,456.59

StringBuilder 类

  1. 一个可变的字符序列。此类提供一个与StringBuffer 兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
  2. StringBuilder 上的主要操作是 appendinsert 方法,可重载这些方法,以接受任意类型的数据。

  • 串行化(对象可以网络传输,也可以保存到文件)

  • StringBuilderfinal 类,不能被继承

  • StringBuilder 对象字符序列仍然存放在其父类 AbstractStringBuilderbyte[] value; 因此字符序列是在堆中

  • StringBuilder 的方法没有做互斥处理,即没有 synchronized 关键字

String、StringBuffer 和 StringBuilder 的比较

  1. StringBuilderStringBuffer 非常类似,均代表可变的字符序列,而且方法也一样

  2. String:不可变字符序列,效率低,但是复用率高

  3. StringBuffer:可变字符序列、效率较高(增删)、线程安全

  4. StringBuilder:可变字符序列、效率最高、线程不安全

  5. String使用注意说明:

    1
    2
    3
    4
    5
    6
    String s = "a";	//创建了一个字符串
    s += "b";
    // 实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b"(也就是"ab")。
    // 如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。
    // 如果这样的操作放到循环中,会极大影响程序的性能
    // =>结论:如果我们对String做大量修改,不要使用String

使用的原则,结论:

  1. 如果字符串存在大量的修改操作,一般使用 StringBufferStringBuilder
  2. 如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder
  3. 如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer
  4. 如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等

Math 类

Math 类包含用于执行基本数学运算的方法,如初等指数,对数,平方根和三角函数。都是静态方法

1
2
3
4
5
6
7
8
9
abs // 绝对值
pow // 求幂
ceil // 对一个数进行上舍入,返回值大于或等于给定的参数
floor // 向下取整
round // 四舍五入
sqrt // 开方
random // 随机数 [0,1) (int)(a + Math.random() * (b - a + 1))
max // 返回两个数最大值
min // 返回两个数最小者

Arrays 类

Arrays 里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1. toString 返回数组的字符串形式
Integer[] arr = {1, 2, 3};
Arrays.toString(arr) // [1, 2, 3]
2. sort 排序 (自然排序和定制排序)
Integer arr[] = {1, -1, 7, 0, 89};
Arrays.sort(arr); // 因为数组是引用类型,所以通过sort排序会直接实参
/**
* sort重载,也可传入一个接口 Comparator 实现定制排序
* 实现Comparator接口的匿名内部类,要求实现 compare 方法
* compare 的返回值>0 还是 <0 影响底层二分排序的的选择,导致排序结果的变化
* 体现 接口编程 + 动态绑定机制 + 匿名内部类的综合使用
*/
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1; // 先下转型
Integer i2 = (Integer) o2;
return i2 - i1; // 逆序 底层:二分
}
});
3. binarySearch 通过二分搜索法进行查, 要求必须排好序
int index = Arrays.binarySearch(arr, 3); // 不存在 则返回 -(应该在的位置 + 1)
4. copyOf 数组元素的复制
Integer[] newArr = Arrays.copyOf(arr, arr.length);
5. fill 数组元素的填充
Integer[] num = new Integer[]{9, 3, 2};
Arrays.fill(num, 99);
6. equals 比较两个数组元素内容是否完全一致
boolean equals = Arrays.equals(arr, arr2);
7. asList 将一组值,转换成list集合
// List接口
List<Integer> asList = Arrays.asList(2, 3, 4, 5, 6, 1);
System.out.println("asList = " + asList); // [2, 3, 4, 5, 6, 1]
System.out.println("运行类型:", + asList.getClass()); // java.util.Arrays$ArrayList 静态内部类

模拟排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.company.arrays_;

import java.util.Arrays;
import java.util.Comparator;

/**
* @author nessaj
* @date 2022/6/18 22:03
*/
public class ArraysSortCustom {
public static void main(String[] args) {
int[] arr = {81, -1, 3, -5, 25};
bubble02(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer) o1; // 自动拆箱
int i2 = (Integer) o2;
return i2 - i1; // return i1 - i2;
}
});
System.out.println(Arrays.toString(arr));
}

// 冒泡
public static void bubble(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}

// 结合 冒泡 + 定制
public static void bubble02(int[] arr, Comparator c) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (c.compare(arr[j], arr[j + 1]) > 0) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
}

System

1
2
3
4
5
6
7
8
1. exit 退出当前程序
exit(0) 表示退出状态
2. arraycopy:复制数组元素,比较适合底层调用,一般使用Array.copyOf完成复制数组
int[] src = {1,2,3};
int[] dest = new int[3]; // dest 当前是 {0, 0, 0}
System.arraycopy(src, 0, dest, 0, 3); // 3 表示length
3. currentTimeMillens: 返回当前时间距离 1970-1-1 的毫秒数
4. gc: 运行垃圾回收机制 System.gc();

BigInteger、BigDecimal

1
2
3
4
5
6
7
8
9
- 应用场景
1. BigInteger 适合保存比较大的整数
2. BigDecimal 适合保存精读更高的浮点数

- 常见方法
1. add 加
2. subtract 减
3. multiply 乘
4. divide 除 // bigDecimal.divide(x, BigDecimal.ROUND_CELING); 指定精度,以防抛出异常

日期类

第一代日期类

  1. Date 精确到毫秒,表示特定的瞬间
  2. SimpleDateFormat 格式和解析日期的类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.company.date_;

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

/**
* @author nessaj
* @date 2022/6/21 20:47
*/
public class Date01 {
public static void main(String[] args) throws ParseException {
Date d1 = new Date(); // 获取当前系统时间
System.out.println("当前日期: " + d1);
Date d2 = new Date(9234567); // 通过指定毫秒数得到时间
System.out.println(d1.getTime()); // 获取某个时间对应的毫秒数

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
String format = sdf.format(d1);
System.out.println(format);

String s = "1996年01月01日 10:20:30 星期一";
Date parse = sdf.parse(s);
System.out.println(parse);
}
}

第二代日期类

  1. Calendar 类(日历)
  2. Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR, MONTH, DAY_OF_MONTH, HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
1
2
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {...}
// 构造器protected,通过getInstance()获取实例
1
2
3
4
5
6
7
8
Calendar c = Calendar.getInstance();
System.out.println(c); // 包含大量字段
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH) + 1);
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.HOUR)); // HOUR_OF_DAY 24时制
System.out.println(c.get(Calendar.MINUTE));
System.out.println(c.get(Calendar.SECOND));

第三代日期类

前面两代日期类的不足分析 JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。

而Calendar也存在问题是:

  1. 可变性:像日期和时间这样的类应该是不可变的。
  2. 偏移性:Date中的年份是从1900开始的,而月份都从0开始。3)格式化:格式化只对Date有用,Calendar则不行。
  3. 此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。
  1. LocalDate(日期)、LocalTime (时间)、LocalDateTime (日期时间) jdk8加入
1
2
3
4
5
6
7
8
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
ldt.getYear();
ldt.getMonthValue();
ldt.getDayOfMonth();
ldt.getHour();
ldt.getMinute();
ldt.getSecond();
  1. DateTimeFormatter 格式日期类
1
2
3
// 类似于 SimpleDateFormat
DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式); // YYYY-MM-DD hh:mm:ss
String str = dtf.format(日期对象);
  1. Instant 时间戳
1
2
3
4
5
6
7
Instant now = Instant.now();
System.out.println(now);

// Instant -> Date
Date date = Date.from(now);
// Date ->Instant
Instant instant = date.toInstant();
  1. 第三代日期类更多方法
1
2
3
4
5
6
LocalLocalDateTime类
MonthDay类: 检查重复事件
是否是闰年
增加日期的某个部分
使用plus方法测试增加时间的某个部分
使用minus方法测试查看一年前和一年后的日期

Java笔记——常用类
https://nessaj7.github.io/2022/06/17/1e13e3ebda05.html
作者
kuhn
发布于
2022年6月17日
许可协议