9.常用类、String、Math、日期

一、常用类

1. 包装类

包装类: 针对八种基本数据类型定义相应的引用类型;

基本数据类型包装类父类
booleanBooleanObject
charCharacter
byteByteNumber
shortShort
intInteger
longLong
floatFloat
doubleDouble

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

jdk5 以前为手动装箱、拆箱,jdk5 以后为自动装箱、拆箱(底层调用的是ValueOf 和 IntValue)

其他包装类 的用法类似。

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
// 拆箱、装箱
public class Warpper01 {
public static void main(String[] args) {
// jdk 5 以前为手动装箱、拆箱
// 装箱
int n1 = 100;
Integer integer = Integer.valueOf(n1);
System.out.println(integer);

// 拆箱
int i = integer.intValue();
System.out.println(i);

// jdk 5 以后 为自动装箱、拆箱
int n2 = 200;
// 装箱
Integer itg = n2;
System.out.println(itg);

// 拆箱
int n3 = itg;
System.out.println(n3);
}
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 包装类 与 String 相互转换
public class Wrapper02 {
public static void main(String[] args) {
// 包装类 与 String 相互转换
Integer int1 = 123;
// 包装类 -> String
String str1 = int1 + "";
String str2 = int1.toString();
String str3 = String.valueOf(int1);

// String -> 包装类
Integer int2 = Integer.valueOf(str1);
Integer integer = new Integer(str2);
}
}

常用方法:

Integer.MIN_VALUE返回最小值
Integer.MAX_VALUE返回最大值
Character.isDigit()是否为字母
Character.isLetter()是否为数字
Character.isUpperCase()是否为大写字母
Character.isLowerCase()是否为小写字母
Character.isWhitespace()是否为空格
Character.toUpperCase()转换为大写字母
Character.tpLowerCase()转换为小写字母

:::danger
只要有基本数据类型,“==”比较的就是值是否相等
:::

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
// 面试题
public class Wrapper03 {
public static void main(String[] args) {
// new 关键字创建的,坑定是不同的对象
// 对象之间用 == 比较,比较的是两个对象的地址
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); // false

Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4); // false

// 底层为 Integer.valueOf()
// Integer 的范围为 -128 ~ 127
Integer i5 = 127;
Integer i6 = 127;
System.out.println(i5 == i6); // true

Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8); // false

Integer i9 = 127; // 从数组中获取
Integer i10 = new Integer(127); // 不同的对象
System.out.println(i9 == i10); // false

// 只要有基本数据类型,== 判断的就是值是否相等
Integer i11 = 127;
int i12 = 127;
System.out.println(i11 == i12); // true

Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14); // true
}
}

二、String

1. String

:::tip
String 特点:

  1. 字符串的字符使用 Unicode 字符编码,一个字符(不区分字母还是汉字)占两个字节;
  2. String 类有多种构造器,构造器重载
    1. new String();
    2. new String([String original]);
    3. new String(char[] a);
    4. new String(char[] a,int startIndex, int count);
  3. String 类实现了接口:
    1. Serializable (string 可以串行:即可以在网络传输)
    2. Comparable (String 对象可以进行比较)
  4. String 是 final 类,不能被其他类继承
  5. String 有属性 private final char value[] ,用于存放字符串内容
    :::
1
2
3
4
// 两种创建 String 对象的区别
String s1 = "hsp";

String s2 = new String("hsp");

:::tip
两种创建 String 对象的区别:

  1. 直接创建:
    1. 先从常量池查看是否有“hsp”数据空间,如果有则直接指向;
    2. 如果没有,则重新创建,然后指向;
    3. s 最终指向的是常量池的空间地址
  2. 利用构造器重建:
    1. 先在堆中创建空间,里面维护了 value 属性,指向常量池的 “hsp” 空间;
    2. 如果常量池没有 “hsp”,则重新创建;如果有,则通过 value 指向;
    3. 最终指向的是堆中的空间地址
      :::
1
2
3
4
5
6
7
8
9
10
11
// 两种创建 String 对象方法
public class String01 {
public static void main(String[] args) {
String a = "hsp"; // 指向常量池
String b = new String("hsp"); // b 先指向堆空间,再通过 value 属性指向常量池
System.out.println(a.equals(b)); // true 值相等
System.out.println(a == b); // false 地址不同
System.out.println(a == b.intern()); // true b.intern() 返回的是常量池的地址
System.out.println(b == b.intern()); // false b 指向堆空间地址
}
}

String 常用方法:

equals区分大小写,判断内容是否相等
equalslgnoreCase不区分大小写,判断内容是否相等
length获取字符串长度
indexOf获取字符在字符串中第一次出现时的索引,找不到返回 -1
lastIndexOf获取字符在字符串中最后 1 次出现的索引,找不到返回 -1
substring截取指定范围的字符串
trim去除前后空格
charAt获取某索引出的字符,注意不能使用 Str[index] 方式
toUpperCase全部转为大写
toLowerCase全部转为小写
concat字符串拼接
replace替换字符串中的字符
split分割字符串
compareTo比较两个字符串大小,根据 ASCii的编码比较,前面的数大,就返回正数,后面的数大,就返回负数,相等则返回 0,如果字符传部分相同,则比较字符串长度
format字符串格式化
toCharArray字符串转为 字符数组
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
50
51
52
53
54
55
56
57
58
59
60
61
62
// String 常用方法案例
public class String01{
public static void main(String[] args) {
// 1.equals 区分大小写比较
String s1 = "hello ";
String s2 = "HELLO ";
String s3 = "Where Are You Doing";
System.out.println(s1.equals(s2)); // false

// 2.equalsIgnoreCase 不区分大小写 比较
System.out.println(s1.equalsIgnoreCase(s2)); // true

// 3.length 获取数组长度
System.out.println(s1.length()); // 6

// 4. indexOf 获取字符第一次出现在字符串中的索引
System.out.println(s1.indexOf("l")); // 2

// 5. lastIndexOf 获取字符 最后一次出现在字符串中的索引
System.out.println(s1.lastIndexOf("l")); // 3

// 6. substring 根据下标截取字符串,左闭右开
System.out.println(s1.substring(2)); // llo
System.out.println(s1.substring(2,4)); // ll

// 7. trim 去除前后空格
System.out.println(s1.trim()); // hello

// 8. charAt 根据下标获取字符
System.out.println(s1.charAt(4)); // o

// 9. toUpperCase 全部大写
System.out.println(s3.toUpperCase(Locale.ROOT)); // WHERE ARE YOU DOING

// 10. toLowerCase 全部小写
System.out.println(s3.toLowerCase(Locale.ROOT)); // where are you doing

// 11. concat 合并数组
System.out.println(s3.concat(s1)); // Where Are You Doinghello

// 12. replace 替换字符串中的字符
System.out.println(s3.replace("Are",s2)); // Where HELLO You Doing

// 13. split 分割字符串
String[] s4 = s3.split(" ");
for (String s:s4){
System.out.println("s3.split = " + s);
}

// 14. compareTo 比较两个字符串的大小, 前者大返回正数,后者大返回负数,相等返回 0
System.out.println(s2.compareTo(s1)); // -32

// 15. toCharArray 转换成字符数组
char[] s5 = s2.toCharArray();
for(char s:s5){
System.out.println("s2.toCharArray = " + s);
}

// 16. format 字符串格式化 %s:字符串,%d:整型,%f:浮点型
System.out.printf("%s,今年%d 岁了,有%.2f压岁钱。","小明",5,100.5); // 小明,今年5 岁了,有100.50压岁钱。
}
}

2. StringBuffer 类

StringBuffer 代表可变的字符序列,可以对字符串内容进行增删,是可变长度

:::tip
String 和 StringBuffer 的区别:

  1. String 保存的是字符串常量,里面的值是不能更改的,
    1. 每次 String 类的更新实际上就是更改地址,效率较低
    2. char[] valre 放在常量池中
  2. StringBuffer 保存的字符串变量,里面的值是可以更改的
    1. 更新时,实际上是改变内容,而不是每次都更新地址
    2. char[] value 放在堆中
      :::
1
2
3
4
5
6
7
8
9
// StringBuffer 构造器
// 1. 创建一个大小为 16 的 char[] 数组,用于存放内容
StringBuffer s1 = new StringBuffer();

// 2. 通过构造器 指定 char[] 大小
StringBuffer s2 = new StringBuffer(100);

// 3. 给一个 字符串 创建 StringBuffer,char[]大小为 str.length() + 16
StringBuffer s3 = new StringBuffer("Hello");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// String 和 StringBuffer 相互转换
public class StringBuffer01 {
public static void main(String[] args) {
// String 和 StringBuffer 相互转换
String s1 = "Hello tom";

// String --> StringBuffer
// 通过构造器转换
StringBuffer sb1 = new StringBuffer(s1);
// 通过 append 转换
StringBuffer sb2 = new StringBuffer();
sb2.append(s1);

// StringBuffer --> String
StringBuffer sb3 = new StringBuffer("study Java");
// 通过 toString 方法转换
String s2 = sb3.toString();
// 通过 String 构造器转换
String s3 = new String(sb3);
}
}

StringBuffer 常用方法:

append
delete(start,end)
replace(start,end,string)改(将 start 到 end 间的内容换掉,不含 end)
indexOf查(查找字符串在字符串中第一次出现的索引,找不到返回-1)
insert插入
length获取长度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// StringBuffer 增删改查
public class String02 {
public static void main(String[] args) {
// StringBuffer 增删改查
// 增
StringBuffer s = new StringBuffer("张三疯");
s.append(',');
s.append("宋无忌").append(",张翠山");
System.out.println("增加后:"+s);
// 删
s.delete(4,7);
System.out.println("删除后:"+s);
// 改
s.replace(4,5,"拳打敬老院,脚踩幼儿园");
System.out.println("修改后:"+s);
// 查
System.out.println("查找 张翠山 :"+s.indexOf("张翠山"));
// 插入
s.insert(4,"他的徒弟们,");
System.out.println("插入后:"+s);
}
}

3. StringBuilder

StringBuilder 是 StringBuffer 的简易替换
两者的方法是一样的
StringBuilder 主要用于单线程

::: note

  1. 一个可变的字符序列;
    1. 不是线程安全,主要用在字符串缓冲区被单线程使用的时候;
    2. 如果可以,建议使用该类,他不 StringBuffer 更快
  2. 主要操作是 append 和 insert 方法,可以重载这些方法,以接受任意类型的数据;
    :::

:::tip
String、StringBuffer、StringBuilder 的比较:

  1. StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且方法也一样;
  2. String: 不可变字符序列,效率低,但是复用率高;
    1. 如果需要做大量的修改,不要使用 String;
  3. StringBuffer: 可变字符序列,效率较高(增删)、线程安全
  4. StringBuilder: 可变字符序列,效率最高,线程不安全
    :::

:::danger
String、StringBuffer、StringBuilder 的选择:

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

三、Math 类

Math 类包含用于执行基本数据运算的方法,如对数、平方根、三角函数等
Math 的方法 基本都是 静态方法,因此可以直接使用类名获取

Math 类常用方法:

abs绝对值System.out.println(Math.abs(-27)); 27
pow求幂(求 a 的 b 次方)System.out.println(Math.pow(3,4)); 81.0
ceil向上取整,返回>=该参数的最小整数System.out.println(Math.ceil(3.1415)); 4
floor向下取整,返回<=该参数的最大整数System.out.println(Math.floor(3.1415)); 3
round四舍五入System.out.println(Math.round(3.1415)); 3
sqrt求开方(参数必须大于等于 0)System.out.println(Math.sqrt(18)); 4.2426406
random随机数(取值为>= 0,< 1的小数)System.out.println(Math.random()); 0.36541574255
min最小数值System.out.println(Math.min(18,22)); 18
max最大数值System.out.println(Math.max(18,22)); 22
1
2
3
4
5
6
7
8
9
10
11
12
// 随机数 - 案例
public class Math02 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(ran(2,7));
}
}
public static int ran(int a, int b){
// 最终返回的是 a <= x < b+1 的小数
return (int)(a + Math.random()*(b-a+1));
}
}

四、Arrays(数组)

常用方法:

toString返回数组的字符串形式
sort排序(从小到大)
binarySearch通过二分法进行查找(必须是有序数组)
copyOf复制数组到新的数组 copyOf(原来的数组,复制的长度)
fill数组元素的填充(替换数值中的所有元素)
equals比较两个数组元素内容是否相同
asList将一组值,转换成 list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 自定义 排序,通过 Comparator接口实现
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// 因为返回值为 int ,需要做下转换
double num = o1.getPrice() - o2.getPrice();
// 通过控制 返回值的正负来确定排序方向
if (num > 0){
return 1;
}else if(num < 0){
return -1;
}else {
return 0;
}
}
});
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
// Arrays 常用方法
public class Arrays01 {
public static void main(String[] args) {
int[] a1 = {1,4,-10,-32,66,43,91};
int[] a2 = {33,44,55,-11,-22,-33};

// toString 返回数组的字符串形式
System.out.println(Arrays.toString(a1));

// sort 排序(从小到大)
Arrays.sort(a1);
System.out.println(Arrays.toString(a1));

// binarySearch 二分法查找,返回数组元素下标(数组必须是有序的)
// 如果找不到,则返回负值,负值为他应该存在的位置
// 如果数组长度不够,则最后赋值为 null
int index = Arrays.binarySearch(a1,6);
System.out.println(index);

// copyOf 复制数组到新的数组 copyOf(原来的数组,复制的长度)
int[] a3 = Arrays.copyOf(a2,3);
System.out.println(Arrays.toString(a3));

// fill 数组填充(替换原来数组中的所有元素)
Arrays.fill(a2,123);
System.out.println(Arrays.toString(a2));

// equals 比较两个数组内容是否一致
int[] arr1 = {1,22,333};
int[] arr2 = {1,22,333};
System.out.println(Arrays.equals(arr1,arr2));
}
}
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 排序 - 案例
public class Arrays02 {
public static void main(String[] args) {
Book[] books = new Book[5];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("三国演义", 120);
books[2] = new Book("西游记", 150);
books[3] = new Book("水浒传", 99);
books[4] = new Book("天龙八部", 113);

System.out.println(Arrays.toString(books));

// 自定义 排序,通过 Comparator接口实现
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
// 因为返回值为 int ,需要做下转换
double num = o1.getPrice() - o2.getPrice();
// 通过控制 返回值的正负来确定排序方向
if (num > 0){
return 1;
}else if(num < 0){
return -1;
}else {
return 0;
}
}
});

System.out.println(Arrays.toString(books));
}
}

class Book{
private String name;
private double price;

public Book(String name, double price) {
this.name = name;
this.price = price;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return name + "\t" + price;
}
}

五、System 类

常见方法:

exit退出当前程序,0 表示正常状态
arraycopy复制数组元素
currentTimeMillens返回当前时间的毫秒数
gc运行垃圾回收机制

:::tip
System.arraycopy(原数组,拷贝起始索引,目标数组,目标数组起始索引,拷贝数量)
:::

六、 BigInteger 和 BigDecimal

BigInteger : 适合保存比较大的整数
BigDecimal : 适合保存精度高的浮点数

:::tip
BigInteger 、BigDecimal注意事项:

  1. 在进行加减乘除操作时,需要使用对应的方法,不能使用基础数据类型的操作方法
    1. 加:add()
    2. 减:subtract()
    3. 乘:multiply()
    4. 除:divide()
      1. BigDecimal 可能会有无限循环小数,所以需要指定精度(BigDecimal.ROUND_CEILING)
      2. 如果有无限循环小数,就会保留 分子 的精度
  2. 创建 BigInteger 对象时,最好以字符串的形式传参;
    :::
1
2
3
4
5
6
7
8
9
10
11
12
// BigInteger - 案例
public class BigInteger01 {
public static void main(String[] args) {
BigInteger bi1 = new BigInteger("12313231231893485938274592784952");
BigInteger bi2 = new BigInteger("123123");

System.out.println(bi1.add(bi2)); // 加
System.out.println(bi1.subtract(bi2)); // 减
System.out.println(bi1.multiply(bi2)); // 乘
System.out.println(bi1.divide(bi2)); // 除
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// BigDecimal - 案例
public class BigInteger01 {
public static void main(String[] args) {
BigDecimal bi1 = new BigDecimal("3.14159263453542423424343");
BigDecimal bi2 = new BigDecimal("3.2342324123");

System.out.println(bi1.add(bi2)); // 加
System.out.println(bi1.subtract(bi2)); // 减
System.out.println(bi1.multiply(bi2)); // 乘
System.out.println(bi1.divide(bi2, BigDecimal.ROUND_CEILING)); // 除
}
}

七、日期类

1.第一代日期( Date)

Date:精确到毫秒,代表特定的瞬间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 第一代 日期
public class Date01 {
public static void main(String[] args) throws ParseException {
// 获取当前时间
Date time = new Date();
System.out.println(time);

// 格式化日期,E 为星期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年 MM月 dd日 hh:mm:ss E");
System.out.println(sdf.format(time));

// 将个时候后的日期转为默认日期
// 默认会报异常,只需将异常抛出即可
String s = "2022年 05月 17日 05:23:48 周二";
Date parse = sdf.parse(s);
System.out.println(parse);
}
}

2. 第二代日期(Calendar 日历)

Calendar: 是一个抽象类,他为特定瞬间与一组日历字段之间的转换提供了方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 第二代日期 - 案例
public class Calendar_ {
public static void main(String[] args) {
// Calendar 是一个抽象类,他的构造器是私有化的,需要用过 getInstance 来创建对象
Calendar c = Calendar.getInstance();
System.out.println(c);

System.out.println(c.get(Calendar.YEAR) + "年");
// 月份是从 0 开始返回的,因此需要 +1
System.out.println((c.get(Calendar.MONDAY) + 1)+ "月");
System.out.println(c.get(Calendar.DATE) + "日");
System.out.println(c.get(Calendar.HOUR) + "时");
System.out.println(c.get(Calendar.MINUTE) + "分");
System.out.println(c.get(Calendar.SECOND) + "秒");
}
}

3. 第三代日期

常见方法:

LocalDate只包含日期,可以获取日期字段
LocalTime只包含时间,可以获取时间字段
LocalDateTime包含日期和时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 第三代日期
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime ld = LocalDateTime.now();
System.out.println(ld);

LocalDate now = LocalDate.now();
System.out.println(now);

LocalTime now1 = LocalTime.now();
System.out.println(now1);

System.out.println(ld.getYear());
System.out.println(ld.getMonth());
System.out.println(ld.getMonthValue());
System.out.println(ld.getDayOfMonth());
System.out.println(ld.getHour());
System.out.println(ld.getMinute());
System.out.println(ld.getSecond());
}
}

:::tip
DateTimeFormatter : 用于格式化日期
yyyy年 MM月 dd日 HH:mm:ss E
:::

1
2
3
4
5
6
7
8
9
10
11
// 格式化日期
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime ld = LocalDateTime.now();
System.out.println(ld);

// 格式化输出日期
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年 MM月 dd日 HH:mm:ss E");
System.out.println(dtf.format(ld));
}
}

时间戳

:::tip
Instant 转换为 Date:Date date = Date.from(Instant);
Date 转换为 Instant: Instant instant = Date.toInstant();
:::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 时间戳
public class LocalDate_ {
public static void main(String[] args) {
// 获取当前时间
Instant now = Instant.now();

// 通过 from 方法把 Instant 转为 Date
Date date = Date.from(now);
System.out.println(date);

// 通过 toInstant 方法把 date 转为 Instant
Instant instant = date.toInstant();
System.out.println(instant);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 日期的加减
public class LocalDate_ {
public static void main(String[] args) {
//
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年 MM月 dd日 HH:mm:ss E");

// 日期增加 890 天
LocalDateTime now1 = now.plusDays(890);
System.out.println(dtf.format(now1));

// 日期减少 120 天
LocalDateTime now2 = now.minusDays(120);
System.out.println(dtf.format(now2));
}
}