Java常用API
什么是API?
- API(Application Programming Interface):应用程序编程接口。
- 简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了。
一、Object
1、Object类的作用:
- 一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类。
- Object类的方法是一切子类都可以直接使用的,所以我们要学习Object类的方法。
2、Object类的常用方法
方法名 | 说明 |
public String toString() | 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址 |
public Boolean equals(Object o) | 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false |
3、Object的toString方法
方法名 | 说明 |
public String toString() | 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址 |
package com.app.d9_api_Object;
/**
学生类:本身就是个子类
*/
public class Student { // extends Object{ // 任何定义的类都继承祖宗类:Object,写不写都默认继承
/**
定义学生属性:姓名、性别、年龄
*/
private String name;
private char sex;
private int age;
/**
必须提供无参构造器、有参构造器可有可无
一旦定义了有参构造器,无参构造器也必须手动定义出来
*/
public Student(){
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
/**
提供变量对应的getter、setter方法,暴露其取值和赋值
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.app.d9_api_Object;
/**
目标:掌握Object类中的toString方法的使用(必须掌握)
*/
public class Test {
public static void main(String[] args) {
// 创建一个学生对象
Student stu1 = new Student("张无忌", '男', 23);
// toString:默认是返回当前对象在堆内存中的地址信息——>类的全限名@内存地址
// com.app.d9_api_Object.Student@776ec8df
String s = stu1.toString();
System.out.println(s);
System.out.println("---------------------------------");
// 直接输出对象变量,默认可以省略toString调用不写的
// 以下两个输出结果是一样的:
System.out.println(stu1.toString()); // com.app.d9_api_Object.Student@776ec8df
System.out.println(stu1); // com.app.d9_api_Object.Student@776ec8df
}
}
com.app.d9_api_Object.Student@776ec8df
---------------------------------
com.app.d9_api_Object.Student@776ec8df
com.app.d9_api_Object.Student@776ec8df
Process finished with exit code 0
(1)问题引出?
- 开发中直接输出对象,默认输出对象的地址其实是毫无意义的。
- 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息。
(2)toString存在的意义?
- 父类
toString()
方法存在的意义就是为了被子类重写,以便于返回对象的内容信息,而不是地址信息!!
package com.app.d9_api_Object;
/**
学生类:本身就是个子类
*/
public class Student { // extends Object{ // 任何定义的类都继承祖宗类:Object,写不写都默认继承
/**
定义学生属性:姓名、性别、年龄
*/
private String name;
private char sex;
private int age;
/**
父类toString()方法存在的意义就是为了被子类重写,
以便于返回对象的内容信息,而不是地址信息!!(重点)
*/
@Override
public String toString() {
return "Student {" + "name=" + name
+ ", sex=" + sex
+ ", age=" + age + "}";
}
/**
必须提供无参构造器、有参构造器可有可无
一旦定义了有参构造器,无参构造器也必须手动定义出来
*/
public Student(){
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
/**
提供变量对应的getter、setter方法,暴露其取值和赋值
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.app.d9_api_Object;
/**
目标:掌握Object类中的toString方法的使用(必须掌握)
*/
public class Test {
public static void main(String[] args) {
// 创建一个学生对象
Student stu1 = new Student("张无忌", '男', 23);
// toString:默认是返回当前对象在堆内存中的地址信息——>类的全限名@内存地址
// 此时父类Object的toString方法已被子类Student重写,
// 按照Java的就近原则,就会找子类的toString,因此不会去找父类的toString方法
String s = stu1.toString();
System.out.println(s);
System.out.println("---------------------------------");
// 直接输出对象变量,默认可以省略toString调用不写的
// 以下两个输出结果是一样的:
System.out.println(stu1.toString());
System.out.println(stu1);
}
}
Student {name=张无忌, sex=男, age=23}
---------------------------------
Student {name=张无忌, sex=男, age=23}
Student {name=张无忌, sex=男, age=23}
Process finished with exit code 0
- 此时父类Object的toString方法已被子类Student重写,按照Java的就近原则,就会找子类的toString,因此不会去找父类的toString方法。
(3)IDEA重写toString方法的快捷键
(4)toString总结
1、Object的toString方法的作用是什么?
- 默认是打印当前对象的地址信息;
- 让子类重写,以便于返回子类对象的内容信息。
4、Object的equals方法
方法名 | 说明 |
public Boolean equals(Object o) | 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false |
(1)问题引出?
- 直接比较两个对象的地址是否相同完全可以用 “==” 替代equals。
(2)equals存在的意义
- 父类
equals
方法存在的意义就是为了被子类重写,以便子类自己来制定比较规则。
- 官方的equals分析:
(3)IDEA重写equals方法的快捷键
(4)equals总结
1、Object的equals方法的作用是什么?
- 默认是否与另一个对象比较地址是否相等;
- 让子类重写,以便于比较2个子类对象的内容是否相等。
二、Objects
1、什么是Objects
- Objects类与Object还是继承关系,Objects类是从 JDK1.7 开始之后才有的。
官方在进行字符串比较时,没有对象自己的equals方法,而是选择了Objects的euqals方法来比较两个对象:
Objects的equals方法比较的结果是一样的,但是更安全。
- Object的equals方法留下的隐患:
- 报错:空指针异常!!说传入的s1是为null的
- Objects的equals方法解决了这个隐患:
- 拿源码来分析一下:左手按住Ctrl键,右手点击鼠标左键
2、Objects的常见方法
方法名 | 说明 |
public static boolean equals(Object a, Object b) | 比较两个对象的,底层会进行非空判断,从而可以避免空指针异常;再进行equals比较。 |
public static boolean isNull(Object obj) | 判断变量是否为null,为null返回true,否则返回false。 |
- 源码也是用 “==” 来判断是否为 null的,但是调用Objects的isNull方法来判断,显得更专业、优雅
总结
1、对象进行内容比较的时候建议使用什么?为什么?
- 建议使用Objects提供的equals方法;
- 比较的结果虽然是一样的,但是更安全。
三、StringBuilder
1、什么是StringBuilder
- StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器。
- 作用: 提高字符串的操作效率,如拼接、修改等。
2、StringBuilder构造器
构造器名称 | 说明 |
public StringBuilder() | 创建一个空白的可变的字符串对象,不包含任何内容。 |
public StringBuilder(String str) | 创建一个指定字符串内容的可变字符串对象 |
3、StringBuilder常用方法
方法名称 | 说明 |
public StringBuilder append(任意类型) | 添加数据并返回StringBuilder对象本身 |
public StringBuilder reverse() | 将对象的内容反转 |
public int length() | 返回对象内容长度 |
public String toString() | 通过toString就可以实现把StringBuilder转换为String |
package com.app.d11_api_StringBuilder;
/**
目标:学会使用StringBuilder操作字符串,最终还需知道它性能好的原因
*/
public class Test {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
// append方法:添加数据并返回StringBuilder对象本身
sb1.append(1);
sb1.append('中');
sb1.append(5.6);
sb1.append(true);
sb1.append("我是你的唯一");
sb1.append("access");
System.out.println(sb1);
// StringBuilder支持链式编程
StringBuilder sb2 = new StringBuilder();
sb2.append("你").append("025").append("我").append("国中");
// reverse方法:将对象的内容反转
System.out.println(sb2.reverse());
// 注意:StringBuilder只是拼接字符串的手段:效率好;
// 最终的目的还是要恢复为String类型
StringBuilder sb3 = new StringBuilder();
sb3.append("123").append("abc");
// 就是不恢复成String类型,怎么样?
// 很多人的方法,都习惯接收一个String类型的密码,你不恢复成String,只能报错!!
// checkPassWord(sb3); // 报错!!需要String,给的却是StringBuilder
// toString方法:恢复成String类型
String result = sb3.toString();
checkPassWord(result);
}
/**
检查密码
*/
public static void checkPassWord(String passWord){
System.out.println(passWord);
}
}
1中5.6true我是你的唯一access
中国我520你
123abc
Process finished with exit code 0
4、StringBuilder的优点
- String类拼接字符串,由于String是不可变字符串,所以一个 “+” 符号,就要在堆内存中产生一个新对象,并且拼接完后,又会将原对象当做垃圾扔掉,非常浪费内存,性能也不好。
- StringBuilder类拼接字符串,只需要创建一个新对象,而且每拼接完一次,就会返回原对象,效率高,性能好。
总结
1、为什么拼接、反转字符串建议使用StringBuilder?
- String:内容不可变、拼接字符串性能差;
- StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。
- 定义字符串使用String;
- 拼接、修改等操作字符串使用StringBuilder。
四、案例:打印整型数组内容
1、需求:
- 设计一个方法用于输出任意整型数组的内容,要求输出成如下格式:
- “该数组的内容为:[11, 22, 33, 44, 55]”
2、分析:
- 1、定义一个方法,用于接收一个数组,将数组内容输出
- 2、当传入的数组不为null时,才开始拼接,否则返回null
- 3、定义循环,遍历数组内容
- 4、在循环外,定义一个空的StringBuilder对象,用于拼接遍历出的数组内容,先拼个左中括号,利用有参构造器,省一行代码
- 5、在循环内,判断每次遍历到的这个数据 是否为 最后一个,是则不用", “隔开,否则用”, "隔开
- 6、拼一个右中括号
- 7、将拼接结果恢复成字符串类型并返回
- 8、模拟一组数据,传入方法
package com.app.d12_api_StringBuilder_test;
/**
目标:通过案例,更深入认识StringBuilder的作用
1、需求:
- 设计一个方法用于输出任意整型数组的内容,要求输出成如下格式:
- “该数组的内容为:[11, 22, 33, 44, 55]”
*/
public class Test {
public static void main(String[] args) {
// 8、模拟一组数据,传入方法
int[] a = {11, 22, 33, 44, 55};
String rs = printArr(a);
System.out.println("该数组内容为:" + rs);
System.out.println("-------------------------------");
int[] b = null;
System.out.println("该数组内容为:" + printArr(b));
System.out.println("-------------------------------");
int[] c = {};
System.out.println("该数组内容为:" + printArr(c));
}
/**
1、定义一个方法,用于接收一个数组,将数组内容输出
*/
public static String printArr(int[] arr){
// 2、当传入的数组不为null时,才开始拼接,
if (arr != null) {
// 4、在循环外,定义一个空的StringBuilder对象,用于拼接遍历出的数组内容,
// 先拼个左中括号,利用有参构造器,省一行代码
StringBuilder sb = new StringBuilder("[");
// 3、定义循环,遍历数组内容
for (int i = 0; i < arr.length; i++) {
// 5、在循环内,判断每次遍历到的这个数据 是否为 最后一个,是则不用", "隔开,否则用", "隔开
sb.append(arr[i]).append(i == arr.length-1 ? "" : ", ");
}
// 6、拼一个右中括号
sb.append("]");
// 7、将拼接结果恢复成字符串类型并返回
return sb.toString();
}else{
// 否则返回null
return null;
}
}
}
该数组内容为:[11, 22, 33, 44, 55]
-------------------------------
该数组内容为:null
-------------------------------
该数组内容为:[]
Process finished with exit code 0
五、Math
1、什么是Math
- 包含执行基本数字运算的方法,Math类没有提供公开的构造器。
- 因为它是工具类,所以构造器是私有的,不能创建对象。
2、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) |
package com.app.d13_api_math;
/**
目标:学习Math的常用方法
*/
public class MathTest {
public static void main(String[] args) {
// 1、取绝对值:返回正数
System.out.println(Math.abs(10)); // 10
System.out.println(Math.abs(-5.6)); // 5.6
// 2、向上取整
System.out.println(Math.ceil(4.0000001)); // 5.0
// 3、向下取整
System.out.println(Math.floor(4.9999999)); // 4.0
// 4、求指数次方
System.out.println(Math.pow(2, 3)); // 2^3 = 8.0
// 5、四舍五入
System.out.println(Math.round(7.455555555)); // 7
System.out.println(Math.round(7.5674334534)); // 8
// 6、获取 0.0-1.0 之间的随机数(包前不包后)
System.out.println(Math.random());
// 如何利用Math类的random方法,获取2-9之间的数
// 第一步——减加法:(2-2)到(9-2) == (0-7) + 2
// 第二步——想办法让 0.0-1.0 变成 0.0-7.0,注意:包前不包后
// 第三步——强制转换成整数,将小数点后的数据全丢掉
int data = (int) (Math.random() * 8) + 2;
System.out.println(data);
}
}
10
5.6
5.0
4.0
8.0
7
8
0.1116523925277888
2
Process finished with exit code 0
六、System
1、什么是System
- System的功能是通用的,都是直接用类名调用即可,所以System不能被实例化。
2、System类的常用方法
方法名 | 说明 |
public static void exit(int status) | 终止当前运行的Java虚拟机,非零表示异常终止。 |
public static long currentTimeMillis() | 返回当前系统的时间毫秒值形式。 |
public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) | 数组拷贝 |
计算机来历
时间毫秒值:
- 计算机认为时间是有起点的, 起始时间:1970年1月1日 00:00:00
- 时间毫秒值:指的是从1970年1月1日 00:00:00走到此刻的总的毫秒数,应该是很大的。1s = 1000ms。
原因:
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。
随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写Unix
package com.app.d14_api_System;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
目标:理解System的常用方法
*/
public class SystemTest {
public static void main(String[] args) {
System.out.println("程序开始...");
// 1、System的exit方法:JVM终止(程序终止)!!慎用!!
// System.exit(0);
// 2、计算机认为起源时间:返回1970-1-1 00:00:00 走到此刻的总的毫秒值:时间毫秒值。
long time = System.currentTimeMillis();
System.out.println(time);
// 分析开始之前,先记录一个起始时间
long startTime = System.currentTimeMillis();
// 进行时间的计算:性能分析
for (int i = 0; i < 10000; i++) {
System.out.println("输出:" + i);
}
// 分析结束,记录一个结束时间
long endTime = System.currentTimeMillis();
// 将毫秒值转换成秒值: (结束时间 - 开始时间) / 1000.0秒
System.out.println((endTime - startTime) / 1000.0 + "s");
// 3、做数组拷贝(了解)
/*
arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length)
第一个参数:被拷贝的数组
第二个参数:从哪个索引位置开始拷贝
第三个参数:拷贝的目标数组
第四个参数:从哪个索引位置开始粘贴
第五个参数:拷贝多少个元素
*/
// 原数组
int[] arr1 = {11, 33, 45, 78, 99};
// 新数组
int[] arr2 = new int[6]; // [0, 0, 0, 0, 0, 0] ==> [0, 33, 45, 0, 0, 0]
// 拷贝数组
System.arraycopy(arr1, 1, arr2, 1, 2);
System.out.println(Arrays.toString(arr2));
System.out.println("程序结束...");
}
}
程序开始...
1659342207328
输出:0
输出:1
输出:2
...
输出:9999
0.059s
[0, 33, 45, 0, 0, 0]
程序结束...
Process finished with exit code 0
七、BigDecimal
1、作用
- 用于解决浮点型运算精度失真的问题。
2、使用步骤
- 创建BigDecimal对象来封装浮点型数据(最后的方式是调用方法)
public static BigDecimal valueOf(double val): 封装浮点数成为BigDecimal对象。
3、BigDecimal常用API
方法名 | 说明 |
public BigDecimal add(BigDecimal b) | 加法 |
public BigDecimal subtract(BigDecimal b) | 减法 |
public BigDecimal multiply(BigDecimal b) | 乘法 |
public BigDecimal divide(BigDecimal b) | 除法 |
public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) | 除法 |
注意事项
【强制】 禁止使用构造方法BigDecimal(double) 的方式把 double 值转化为 BigDecimal 对象。
说明:BigDecimal(double) 存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。
如:BigDecimal g = new BigDecimal(0.1F);
实际的存储值为:0.10000000149
。
正例: 优先推荐入参为 String 的构造方法,或使用 BigDecimal 的 valueOf
方法,此方法内部其实执行了 Double 的 toString,而 Double 的 toString 按 double 的实际能表达的精度对尾数进行了截断。
BigDecimal recommend1 = new BigDecimal("0.1");
BigDecimal recommend2 = BigDecimal.valueOf(0.1); // 推荐
package com.app.d15_api_bigdecimal;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
目标:学会使用BigDecimal解决精度失真的问题
*/
public class BigDecimalTest {
public static void main(String[] args) {
// 浮点型运算的时候直接 + - * / 可能会出现数据失真(精度问题)
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
System.out.println("---------------------------");
double a = 0.1;
double b = 0.2;
double c = a + b;
System.out.println("a + b = " + c);
System.out.println("---------------------------");
// 包装浮点型数据成为大数据对象 BigDecimal
BigDecimal a1 = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
BigDecimal c1 = a1.add(b1); // 加
BigDecimal c2 = a1.subtract(b1); // 减
BigDecimal c3 = a1.multiply(b1); // 乘
BigDecimal c4 = a1.divide(b1); // 除
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println("----");
// checkValue(c1); // 报错!!因为别人写的方法是要接收一个double类型的参数,这里却传入一个BigDecimal类型的
// 注意:BigDecimal只是用来计算的手段,最终目的还是要恢复成double类型
// 因为别人写方法的时候,都是用double接收小数类型的参数
// 所以,BigDecimal的doubleValue方法可以直接转成double
// 相等于我们之前说过的,StringBuilder的toString方法可以直接转成String一个道理
double rs1 = c1.doubleValue();
double rs2 = c2.doubleValue();
double rs3 = c3.doubleValue();
double rs4 = c4.doubleValue();
checkValue(rs1);
checkValue(rs2);
checkValue(rs3);
checkValue(rs4);
System.out.println("-----");
// 注意事项:BigDecimal是一定要精度运算的
BigDecimal a2 = BigDecimal.valueOf(10.0);
BigDecimal b2 = BigDecimal.valueOf(3.0);
/**
参数一:除数;参数二:保留小数位;参数三:舍入模式
*/
BigDecimal c22 = a2.divide(b2, 2, RoundingMode.HALF_UP); // 3.333333333
System.out.println(c22); // 3.333333333 约等于 3.33
}
public static void checkValue(double d){
System.out.println(d);
}
}
0.09999999999999999
0.6799999999999999
101.49999999999999
0.013009999999999999
---------------------------
a + b = 0.30000000000000004
---------------------------
0.3
-0.1
0.02
0.5
----
0.3
-0.1
0.02
0.5
-----
3.33
Process finished with exit code 0
BigDecimal总结
1、BigDecimal的作用是什么?
- 解决浮点型数据的精度失真问题。
2、BigDecimal的对象如何获取?
- BigDecimal b = BigDecimal.valueOf(0.1);