14_常用API:Object类,Math类,System类,BigDecimal类,包装类,Arrays 工具类

Java 常用API

Object 类

所有的类,都直接或者间接的继承了 Object 类

public String toString()

默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址

存在意义:子类重写后可以返回所需对象的内容,替换原先的地址;

1
2
3
4
5
6
7
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

getClass().getName() : 类名称, 全类名(包名 + 类名)
Integer.toHexString() : 转十六进制
hashCode() : 返回对象内存地址 + 哈希算法, 算出来的整数 (哈希值)

注: 使用打印语句打印对象名时, println()方法在源码层面自动调用该对象的toString方法.

public static String valueOf(Object obj) {
   return (obj == null) ? "null" : obj.toString();
}

toString()示例:

1
2
3
4
5
6
7
8
9
10
11
class A {
private String name;
private int age;
@Override
public String toString() {
return "A{name = " + name + ", age = " + age + "}";
}
}
使用:
A a = new A();
System.out.println(a); //等价于System.out.println(a.toString());
public Boolean equals(Object o)

默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false

存在意义:子类重写后定义自己的比较规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class A {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if(obj instancerof A){ //判断是不是父子类的关系
//向下转型,调用子类特有的成员
A a = (A)obj;
return this.age == a.age && this.name.euals(stu.name);
}else{
return false;
}
}
}
IDEA中自带的重写equals()方法分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public boolean equals(Object o) {
// this : stu1
// o : stu2
if (this == o) {
// 两个对象做地址值的比较, 如果地址相同, 内容肯定相同
return true;
}

// 代码要是能够走到这里, 代表地址肯定不相同,同时stu1不为null
// 如果stu2为null, 返回false
// this.getClass() != o.getClass() : 两个对象的字节码是否相同,如果字节码不同, 代表类型不相同, 返回false
if (o == null || this.getClass() != o.getClass()) {
return false;
}

// 代码要是能够走到这里, 类型相同.
// 则向下转型
Student student = (Student) o;
// 比较
return this.age == student.age && Objects.equals(this.name, student.name);
}
Objects的常见方法
1
2
3
4
public static boolean equals(Object a, Object b)
//比较两个对象 特点:底层先进行非空判断,以避免空指针异常,然后再equals()比较;
public static boolean isNull(Object obj)
//判断变量是否为 null 底层逻辑就是判断是否为null,很简单一般不用该方法
分析:
  • Objects.equals 和 ***.equals方法的区别:

实现逻辑: Objects.equals方法, 内部依赖于我们自己所编写的equals
优点区别: Objects.equals方法, 内部带有非null判断,避免空指针异常

1
public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b));}

a == b : 如果地址相同, 返回为true;短路 || 功能:如果左边为true, 右边不执行

即:如果地址相同, 直接返回true

a != b : 如果地址不相同, 返回false, 短路 || : 左边为false, 右边继续执行.

a != null : a为null,返回false时,短路 && : 左边为false, 右边不执行; 则a不调用equals(),避免了空指针异常问题

a != null : 返回true时a不为null,短路 && : 左边为true, 右边执行 a.equals(b)

Math 类

java.lang___不需要导包,工具类,所有方法都是静态的,私有了构造方法不允许调用 Math.—();调用

常用方法名 作用
public static int abs(int a) 获取参数绝对值
public static double ceil(double a) 向上取整
public static double floor(double a) 向下取整
public static int round(float a) 四舍五入
public static int max(int a,int b) 获取两个int值中的较大值
public static double pow(double a,double b) 返回a的b次幂的值
public static double random() 返回值为double的随机值,范围[0.0,1.0)

System 类

同Math类,所有方法都是静态的,类名调用

常用方法名 作用
public static void exit(int status) 终止当前运行的 Java 虚拟机,非零表示异常终止
public static long currentTimeMillis() 返回当前系统的时间毫秒值形式,从1970年1月1日0时0分0秒到现在[由于时区不同,中国为8时0分0秒]
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 数组拷贝 参数:(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数/长度)
1
2
3
4
5
6
7
8
9
10
//currentTimeMillis()使用
long start = System.currentTimeMillis();
/………………/ //统计这段代码的运行时间 单位毫秒
long end = System.currentTimeMillis();
long time = end - start;

// arraycopy(Object src, int srcPos, Object dest, int destPos, int length)使用
int[] arr = {1,2,3,4};
int[] arr2 = new int[3];
System.arraycopy(arr, 1, arr2, 0, 3); //arr2:{1,2,3}

BigDecimal 类

解决小数运算中的不精确问题:

1
2
3
double num1 = 0.1;
double num2 = 0.2;
System.out.println(num1 + num2); //0.300000000000004

构造方法

public BigDecimal(double val) 不常用:还是会导致精度问题
public BigDecimal(String val)
public static BigDecimal valueOf(double val)
1
2
BigDecimal bd1 = BigDecimal.valueOf(1.0);
BigDecimal bd2 = new BigDecimal("1.0");

常用方法

方法名 作用
public BigDecimal add(BigDecimal b) 加法
public BigDecimal subtract(BigDecimal b) 减法
public BigDecimal multiply(BigDecimal b) 乘法
public BigDecimal divide(BigDecimal b) 除法
public BigDecimal divide (BigDecimal b,精确位数,舍入模式) 除法[保留几位小数]
b.doubleValue() 转成double类型
1
2
3
4
5
6
7
8
BigDecimal bd1 = BigDecimal.valueOf(0.10);
BigDecimal bd2 = BigDecimal.valueOf(0.03);

bd1.add(bd2); //0.13
bd1.subtract(bd2); //0.07
bd1.multiply(bd2); //0.003
bd1.divide(bd2); //此时会报错,运算错误,除不尽
bd1.divide(bd2, 2, RoundingMode.HALF_UP); // 3.33
舍入模式
  • RoundingMode.UP 进一法
  • RoundingMode.DOWN 去尾法
  • RoundingMode.HALF_UP 四舍五入

包装类

将基本数据类型, 包装成类 (变成引用数据类型)

基本数据类型 引用数据类型
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean

Integer 类

Integer 和 int 的转换
  • 手动装箱: 调用方法, 手动将基本数据类型, 包装成类
1
2
public Integer(int value)  			   //构造方法 
public static Integer valueOf(int i) //静态方法
  • 手动拆箱: 调用方法, 手动将包装类, 拆成(转换)基本数据类型
1
public int intValue()                //以 int 类型返回 Integer对象 的值
1
2
Integer it = Integer.value(1);
int i = it.inValue(it);

  • JDK5版本开始, 可以自动拆装箱 :

​ 自动装箱 : 可以将基本数据类型直接赋值给包装类的变量
​ 自动拆箱 : 可以将包装类的数据直接赋值给基本数据类型变量

1
2
3
int num = 10;
Integer it = num;
int i = it;
常用方法
方法名 说明
public static String toBinaryString(int i) 转换成二进制
public static String toOctalString(int i) 转换成八进制
public static String toHexString(int i) 转换成十六进制
public static int parseInt(String s) 将字符串类型整数转换成int类型
1
2
3
String s = "100";
System.out.println(s + 100); // 100100
System.out.println(Integer.parseInt(s) + 100); // 200
实例

将 String s = “1,2,3,4”; 转换为整数并存入数组。

1
2
3
4
5
6
7
8
String s = "1,2,3,4";
// 1. 逗号为分隔符
String[] arr = s.split(",");
// 2. 遍历字符串数组转换成int型,存入num[]数组
int[] num = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
num[i] = Integer.parseInt(arr[i]);
}
转换内部逻辑
1
2
3
4
5
6
7
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2); // true

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

原因:自动装箱的时候, 如果装箱数据在-128~127之间, ==比较结果为true, 范围外为false

自动装箱原理 : 调用 Integer.valueOf(); 方法

逻辑代码
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
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

注:
static final Integer[] cache; //cache是一个数组
static final int low = -128;
static final int high = 127; //静态内部类中h赋值给high
// 部分static{}代码
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
}
1
2
3
4
5
6
public static Integer valueOf(int i) { 		  //i = 127
if (i >= -128 && i <= 127) {
return IntegerCache.cache[255]; //i + (-IntegerCache.low) = 255
}
return new Integer(i);
}
  • ​ 如果装箱数据不在 -128 ~ 127 , 重新创建新的对象 new Integer(i); 堆中重新开辟内存,此时==比较时候是两个不同内存地址的数据
  • ​ 如果装箱数据在 -128 ~ 127 , 不会创建新对象, 从cache数组中, 取出提前创建好的Integer对象返回

Integer类中, 定义的 Integer[] cache存储了256个Integer对象: -128 ~ 127

总结

实际比较时,调用qual()方法,包装类重写了父类的equal()方法,就是比较数据的

Arrays 工具类

数组操作工具类

常用方法 说明
public static String toString(类型[] a) 将数组元素拼接为带有格式的字符串
public static boolean equals(类型[] a, 类型[] b) 比较两个数组内容是否相同
public static int binarySearch(int[] a, int key) 查找元素在数组中的索引 (二分查找法)
public static void sort(类型[] a) 对数组进行默认升序排序

注:public static int binarySearch(int[] a, int key): 如果查找的元素, 在数组中不存在: 返回 (-(插入点) - 1)

1
2
3
4
5
6
7
8
9
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = {2, 1, 3, 4, 5};

System.out.println(Arrays.toString(arr1)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.equals(arr1, arr2)); // false
System.out.println(Arrays.binarySearch(arr1, 2)); // 1
System.out.println(Arrays.binarySearch(arr1, 6)); // -(5)-1 = -6
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2)); // [1, 2, 3, 4, 5]

14_常用API:Object类,Math类,System类,BigDecimal类,包装类,Arrays 工具类
http://example.com/2023/02/14/常用API/
作者
zhanghao
发布于
2023年2月14日
许可协议