Java 基础类库

Java 提供了丰富的基础类库,利用它们可以提高开发效率,降低开发难度。

一、基本类型包装类

1. 什么是包装类?

Java 为了照顾程序员的传统习惯,提供了 8 种基本类型。

又为了能够将基本类型当作 Object 使用,Java 提供了它们对应的包装类,具体对应关系如下:

2. 基本数据类型与包装类的手动转换

(1) 已过时的基本类型转包装类

1
Integer integer = new Integer(123);

已过时,不建议使用,使用静态方法 valueof() 会更好

(2) valueOf()

用于基本类型包装类

1
Integer integer = Integer.valueOf(123);

(3) xxxValue()

用于包装类基本类型

1
2
Integer integer = Integer.valueOf(123);
int i = integer.intValue();

3. 自动装箱和自动拆箱

(1) 自动装箱

可以将基本类型的数据直接赋给对应的包装类变量。

1
Integer integer = 123;

(2) 自动拆箱

可以将包装类对象直接仿佛给对应的基本类型变量。

1
2
Integer integer = 123;
int i = integer;

4. 基本类型和字符串的转换

(1) 字符串转基本类型

parseXxx()
1
int i = Integer.parseInt("123");
valueOf()
1
int i = Integer.valueOf("123");

(2) 基本类型转字符串

valueOf()
1
String str = String.valueOf(123);
字符串连接
1
String str = "" + 123;

5. 数值比较

包装类和包装类之间、基本类型和包装类之间可以进行比较,比较的方法是“自动拆箱”后进行比较。

1
2
3
4
5
Integer integer1 = 1230;
Integer integer2 = 1240;
System.out.println(integer1 < integer2); // true
int i = 1220;
System.out.println(i < integer2); // true

6. 判断是否相等

1
2
3
4
5
6
7
Integer integer1 = 1240;
Integer integer2 = 1240;
System.out.println(integer1 == integer2); // false
System.out.println(integer1 == 1240); // true
Integer integer3 = 124;
Integer integer4 = 124;
System.out.println(integer3 == integer4); // false

在判断两个包装类是否相等时,仅当两个变量指向同一个实例时,Java 才认为它们相等。

对于 Integer integer1 = 1240;Integer integer2 = 1240; ,他们虽然数值相同,但是两个不同的实例,因此被判定为不相等。

Integer integer3 = 124;Integer integer4 = 124; 相等的原因在于 Java 的缓存机制

7. 缓存机制

Java 会将 -128~127 之间的整数自动装箱为 Integer 实例,并放入数组中缓存起来。如果创建 -128~127 之间的整数,默认会直接指向数组中的元素。

因此,创建多个同等数值的 Integer 实例,它们实际上都是同一个,指向数组中的同一个元素。

二、常用类

1. Object

方法 说明
obj1.equals(Object obj2) 判断两个对象是否相等
toString() 对象的字符串表示

通常会重写类的 equals() 和 toString()

2. Objects

Objects 提供了一些工具方法用来操作对象。

使用 Objects 的好处在于,防止因为对象是空指针而报错。

1
2
System.out.println(object);  // 若该对象是空指针,则会报错
System.out.println(Objects.toString(object)); // 如果该对象是空指针,输出null

3. Arrays

(1) Arrays 是什么?

Java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的,即所有方法都是类方法,可以由类名直接调用。

(2) 方法

查询元素
1
int binarySearch(type[] a, [int fromIndex, int toIndex,] type key)

在数组中查询元素下标,若不存在则返回负数,要求数组升序排列(只在 fromIndex 到 toIndex 中查找)

复制数组
1
type[] copyOf(type[] original, [int fromIndex, int toIndex,] int length)

复制 original 数组到新数组中,以方法返回值的形式返回(只复制 fromIndex 到 toIndex 中的元素)

若 length 大于 original 数组长度,多余部分会置为零;

若 length 小于 original 数组长度,则只截取 length 个。

填充元素
1
void fill(type[] a, [int fromIndex, int toIndex,] type val)

将数组中的所有元素都赋值为 val (只填充 fromIndex 到 toIndex 中的元素)

排序
1
void sort(type[] a, [int fromIndex, int toIndex])

对数组中的元素进行排序(只排序 fromIndex 到 toIndex 中的元素)

判断是否相等
1
boolean equals(type[] a1, type[] a2)

判断两个数组是否相等,相等则返回 true 。

转换为字符串
1
String toString(type[] a)

将数组转换为字符串,以方法返回值的形式返回。

(3) 新增方法

通过多 CPU 并行提升了性能

4. String

(1) 访问字符串元素

1
str.charAt(索引)

(2) 获得字符串长度

1
str.length()

(3) 字符串比较

假设有两个字符串 str1str2

  • 若用 == 作比较,则比较的是指针指向的地址值

  • 如果希望比较字符串的是否相同,应该通过 equals 方法进行比较:

    1
    str1.equals(str2)

5. StringBuffer 和 StringBuilder

即可变字符串

(1) 什么是 StringBuffer 和 StringBuilder?

字符串在内存中会以常量的形式进行存储。如果对字符串进行“修改”,在内存中发生的情况是:新建一个“被修改”的字符串,它将于原字符串一起放置在内存之中。

如果希望对字符串进行修改,且不产生新的字符串对象,便可以使用 StringBuffer 和 StringBuilder 类,它们的对象能够被多次修改,并且不产生新的对象。

(2) StringBuffer 和 StringBuilder 的区别

  • StringBuilder 的方法不是线程安全的(不能同步访问)
  • StringBuilder 相较于 StringBuffer 有速度优势
  • 多数情况下建议使用 StringBuilder

(3) 常用方法

将指定的字符串追加 StringBuilder 到对象中

1
public StringBuilder append(String s)

将 StringBuilder 对象反转

1
public StringBuilder reverse()

将 StringBuilder 对象转化为字符串

1
public String toString()

6. Math

方法 说明
Math.abs(int a) 返回绝对值
Math.round(float a) 返回最接近的整数
Math.ceil(double a) 返回大于等于参数的整数(以 double 类型返回)
Math.floor(double a) 返回小于于等于参数的整数(以 double 类型返回)
Math.max(int a, int b) 返回较大值
Math.min(int a, int b) 返回较小值
Math.pow(double a, double b) 返回 a 的 b 次方
Math.sqrt(double a) 返回算术平方根
Math.random() 返回随机数,范围在 0 ~ 1 之间

7. Random 和 ThreadLocalRandom

(1) 什么是 Random?

Random 用于生成伪随机数。

(2) 构造方法

使用当前的时间作为种子
1
Random rand = new Random();
指定 long 数值作为种子
1
Random rand = new Random(num);

(3) 常用方法

方法 说明
nextDouble() 生成 0~1 的伪随机 double 数
nextFloat() 生成 0~1 的伪随机 float 数
nextInt() 生成伪随机 int 数
nextInt(num) 生成 0~num 的伪随机 int 数

(4) 伪随机

Random 生成数值是一种伪随机,当两个 Random 对象的种子相同,且调用方法的顺序也相同,则它们会产生相同的数字序列。

(5) ThreadLocalRandom

是 Random 的增强版,在并发访问的环境下,使用 ThreadLocalRandom 可以减少多线程资源竞争,从而保证系统具有更好的线程安全性。

8. BigDecimal

为了解决 float、double 精度丢失的问题,

1
double num = 0.1;

此时 num 并不等于 0.1,而是近似于 0.1,这是由浮点数的底层存储方式决定的。

Java 提供了 BigDecimal 类,它提供了大量的构造器,可以通过基本类型、数值字符串、数值数组等创建 BigDecimal 对象。通过 BigDecimal 可以实现不丢失精度的计算。

需要注意的是:

如果希望通过浮点数创建 BigDecimal 对象,应该通过 valueOf 方法,或先将浮点数转化为字符串后再进行创建。

9. System

方法 说明
System.currentTimeMillis() 获取系统当前时间(毫秒值)
System.exit(0) 结束程序,0 表示正常退出
System.gc() 提醒虚拟机调用垃圾回收器

10. Scanner

方法 说明
next() 获得下一个输入项,作为字符串处理
nextXxx() 获得下一个 Xxx 类型输入项
nextLint() 获取下一行输入项,作为字符串处理
hasNext() 判断是否有下一个输入项
hasNextXxx() 判断是否有下一个 Xxx 类型输入项
hasNextLine() 判断是否有下一行输入
useDelimiter(String pattern) 用于设置读取数据时的分隔符

默认情况下,Scanner 读取数据以空格、Tab、回车作为分隔;

使用 nextLine 时,Scanner 以回车作为分隔

三、日期、时间

1. Date

(1) 什么是 Date?

Date 既可以用来处理日期,也可以用来处理时间。因为历史悠久,很多方法都已经过时,不再推荐使用。

(2) 构造器

生成一个代表当前日期时间的 Date 对象:

1
Date()

根据参数生成 Date 对象:

参数应该是 long 类型,为指定时间和”时间纪元”相差的毫秒数

1
Date(long time)

(3) 方法

方法 说明
date1.after(Date date2) 判断 date1 是否在 date2 之后
date1.before(Date date2) 判断 date1 是否在 date2 之前
date.getTime() 返回日期对应的 long 整数
date.setTime(long time) 设置时间

2. Calendar

(1) 什么是 Calendar?

Calendar 是一个抽象类,用于表示日历,它是所有日历类的模板。

Java 本身提供了 GregorianCalendar 类,对应公历。

(2) 新建 Calendar 对象

1
Calendar calendar = Calendar.getInstance()

(3) Calendar 与 Date 的互相转换

Calendar 转 Date
1
Date date = calendar.getTime()
Date 转 Calendar
1
2
Calendar calendar = Calendar.getInstance()
calendar.setTime(date)

(4) 常用方法

方法 说明
get(字段) 获得指定字段的值
add(字段, int amount) 将指定字段添加指定的时间量
set(int year, int month, int date) 设置当前日期的年、月、日

参考