API的基本使用
- 概述:API(Application Programming interface)就是应用程序接口。简单来说,就是Java帮我们写好的可以直接使用的一些方法。
Math类
- Math包含执行基本数字运算的方法
- 没有构造方法,所有成员都是静态的(static),可以直接通过类名调用
常用方法
方法名 | 说明 |
---|---|
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 int min(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类
概述
- 不能被实例化(不能被创建对象)
常用方法
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的Java虚拟机,非0表示异常终止 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
arraycopy(数据源数组,起始索引,目的地数组,起始索引,拷贝个数) | 数组copy |
Object类
概述:每个类都可以将Object作为父类。所有类都直接或间接的继承自该类
- 直接打印一个对象就是打印这个对象的toString方法的返回值
- Object类的toString方法得到的是对象的地址值,我们一般会对toString方法进行重写
构造方法:public Object();
常用方法
方法名 | 说明 |
---|---|
public String toString() | 返回对象的字符串表示形式。建议所有子类重写该方法,自动生成 |
public boolean equals(另一个对象) | 比较对象是否相等。默认比较地址,重写可以比较内容,自动生成 |
面试题
public class InterviewTest{
public static void main(String[] args){
String s1 = "abc";
StringBuilder sb = new StringBuilder("abc");
System.out.println(s1.equals(sb)); // false
// 此时调用的是String类中的equals方法
// 会先判断是否是字符串,若不是字符串则不会比较属性值,直接返回false
System.out.println(sb.equals(s1)); // false
// 此时调用的是StringBuilder中的equals方法,StringBuilder并没有该方法,则继承Object中的equals方法
// 即比较地址值,返回false
}
}
Objects
- 无构造方法,但所有成员方法都是静态方法(static),可以直接根据类名调用
常用方法
方法名 | 说明 |
---|---|
public static String toString(对象) | 返回参数中对象的字符串表示形式 |
public static String toString(对象,默认字符串) | 返回对象的字符串表示形式,如果对象为空,返回默认字符串 |
public static Boolean isNull(对象) | 判断对象是否为空 |
public static Boolean nonNull(对象) | 判断对象是否不为空 |
BigDecimal类
构造方法
方法名 | 说明 |
---|---|
BigDecimal(double val) | 参数为double |
BigDecimal(String val) | 参数为String |
常用方法
作用:可以用来精确计算(如果想要精确运算,请使用字符串构造)
方法名 | 说明 |
---|---|
public BigDecimal add(另一个BigDecimal对象) | 加法 |
public BigDecimal subtract(另一个BigDecimal对象) | 减法 |
public BigDecimal multiply(另一个BigDecimal对象) | 乘法 |
public BigDecimal divide(另一个BigDecimal对象) | 除法 |
public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) | 除法 |
舍入模式:
进一法:ROUND_UP
去尾法:ROUND_FLOOR
四舍五入:ROUND_HALE_UP
Integer类
- 概述:Integer类包装一个对象中的原始类型int的值。(基本类型包装类)
包装类
将基本数据类型封装为对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用的操作之一:用于基本数据类型与字符串之间的转换
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Integer类的使用
构造方法
public Integer(int value)
根据int创建Integer对象 (过时)public Integer(String s)
根据String值创建Integer对象 (过时)public static Integer valueof(int i)
返回表示指定的int值的Integer实例public static Integer valueof(String s)
返回一个保存指定值的Integer对象String
自动装箱
- 装箱:把一个基本数据类型变成与之对应的包装类
- 自动:Java底层会帮我们自动的调用valueof方法
- 使用格式:
Integer i1 = 100;
自动拆箱
- 拆箱:把一个包装类型,变成对应的基本数据类型
- 使用格式:
int i - i1;
i1为Integer对象
成员方法
static int parseInt(String s)
将字符串类型的整数变成int类型的整数
// int 转换为 String
// 方式一:+ ""
int i1 = 100;
String s1 = i1 + "";
// 方式二:可以调用String类中的valueof方法
String s2 = String.valueof(i1);
练习
// 案例:字符串中数据的处理
// 需求:有一个字符串:"91 27 46 38 50",把其中的每一个数存到int类型的数组中
public class MyIntegerDemo{
public static void main(String[] args){
String s = "91 27 46 38 50";
// 获取字符串中的每一个数字
String[] strArr = s.split(" ");
// 创建一个int类型数组
int[] numberArr = new int[strArr.length];
// 把strArr中的数据进行类型转换并存入到int数组中
for(int i = 0; i < strArr.length; i++){
int number = Integer.parseInt(strArr[i]);
numberArr[i] = number;
}
// 遍历int类型的数组
for(int i = 0; i < numberArr.length; i++){
System.out.println(numberArr[i]);
}
}
}
数组的高级操作-1
- 基本查找:根据索引,遍历查找相应的元素
二分查找
- 前提:数组的元素按照大小、顺序排列
- 每次去掉一半的查找范围
步骤
- 定义两个变量,表示要查找的范围。默认min=0,max = 最大索引
- 循环查找,但是min <= max
- 计算出mid的值
- 判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
- 如果要查找的值在mid左半边,那么min值不变,max = mid - 1,继续下次循环查找
- 如果要查找的值在mid右半边,那么max值不变,max = mid + 1,继续下次循环查找
- 当min > max时,表示要查找的元素在数组中不存在,返回-1
public class MyBinarySearchDemo{
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int number = 10;
int index = binarySearchForIndex(arr, number);
System.out.println(index);
}
private static int binarySearchForIndex(int[] arr, int number) {
// 定义查找的范围
int min = 0;
int max = arr.length - 1;
// 循环查找 min <= max
while (min <= max) {
// 计算中间位置
int mid = (min + max) >> 1; // 右移一位,也是除以二的意思
// mid指向的元素 > number
if (arr[mid] > number) {
// 表示要查找的元素在左边
max = mid - 1;
}
// mid指向的元素 < number
else if (arr[mid] < number) {
// 表示要查找的元素在右边
min = mid + 1;
} else {
// mid指向的元素 == number
return mid;
}
}
// 如果min大于了max就表示元素不存在,返回-1
return -1;
}
}
冒泡排序
- 排序:将一组数据按照固定的规则进行排列
- 冒泡排序:相邻的数据两两比较,小的放前面,大的放后面。
步骤
- 相邻的元素两两比较,大的放右边,小的放左边,找到最大值
- 第一次循环结束,最大值已经找到,在数组的最右边
- 下一次只要在剩余的元素中找最大值就可以了
- 如果有n个数据进行排序,总共需要比较n - 1次
- 每一次比较完毕,下一次的比较就会少一个数据参与
public class MyBubbleSortDemo{
public static void main(String[] args){
int[] arr = {3, 5, 2, 1, 4};
bubbleSort(arr);
printArr(arr);
}
private static void bubbleSort(int[] arr){
// 循环排序
// 外层循环控制次数,比数组的长度少一次
for(int i = 0; i < arr.length - 1; i++){
// 内存循环就是实际比较的次数
for(int j = 0; j < arr.length - 1 - i; j++){
// -1为了让数组不越界,-i 是每轮结束后都会减少比较
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
private static void printArr(int[] arr){
// 循环遍历
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
递归
概述:以编程角度来看,递归指的是方法定义中调用方法本身的现象
解决问题的思路:把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
递归解决问题要有两个内容
- 递归出口:否则会出现内存溢出
- 递归规则:与原问题相似的规模较小的问题
案例
// 求1~100的和(递归实现)
public class MyFactorialDemo1{
public static void main(String[] args){
int sum = getSum(100);
System.out.println(sum);
}
private static int getSum(int i){
if(i == 1){
return 1;
}else{
return i + getSum(i - 1); // i + (i - 1)的和
}
}
}
// 需求:用递归求5的阶乘,并把结果在控制台输出
public class MyFactorialDemo2{
public static void main(String[] args){
int result = getJc(5);
System.out.println(result);
}
private static int getJc(int i){
// 出口
if(i == 1){
return 1;
}else{
// 规则(递归下一次调用的,一定更接近出口)
return i * getJc(i - 1);
}
}
}
数组的高级操作-2
快排
- 冒泡排序算法中,一次循环结束,就相当于确定了当前的最大值,也能确定最大值在数组中应存入的位置。
- 快速排序算法中,每一次递归时以第一个数为基准数,找到数组中所有比基准数小的。再找到所有比基准数大的。小的全部放左边,大的全部放右边,确定基准数的正确位置
public class MyQuiteSortDemo{
public static void main(String[] args) {
int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
quiteSort(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
private static void quiteSort(int[] arr, int left, int right) {
if (right < left) {
return;
}
// 记录两个值
int left0 = left;
int right0 = right;
// 计算出基准数
int baseNumber = arr[left0];
while (left != right) {
// 1.从右开始找比基准数小的
while (arr[right] >= baseNumber && right > left) {
right--;
}
// 2.从左开始找比基准数大的
while (arr[left] <= baseNumber && right > left) {
left++;
}
// 3.交换两个值的位置
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
// 4. 基准数归位
int temp = arr[left];
arr[left] = arr[left0];
arr[left0] = temp;
// 再次递归调用方法
quiteSort(arr, left0, left - 1);
quiteSort(arr, left + 1, right0);
}
}
Arrays
Arrays类包含用于操作数组的各种方法
方法名 | 说明 |
---|---|
public static String toString(int[] a) | 返回指定数组的内容的字符串表示形式 |
public static void sort(int[] a) | 按照数字顺序排列指定的数组 |
public static int binarySearch(int[] a,int key) | 利用二分查找返回指定元素的索引 |
public static int binarySearch(int[] a,int key)
1.数组必须有序
2.如果查找的元素存在,那么返回的是这个元素实际的索引
3.如果要查找的元素不存在,那么返回的是(-插入点-1)
插入点:如果这个元素在数组中,他应该在的索引位置
时间日期类
- 世界标准时间:格林尼治时间/格林威治时间,简称GMT
- 中国标准时间:世界标准时间 + 8小时
时间换算公式
1秒 = 1000毫秒
1毫秒 = 1000微秒
1微秒 = 1000纳秒
- 计算机中的时间原点:1970年1月1日 00:00:00
Date类
- Date代表了一个特定的时间,精确到毫秒
- 构造方法
| 方法名 | 说明 |
| :----------------------: | :--------------------------------------------------------------------------: |
| public Date() | 创建一个Date对象,表示默认时间(电脑中的当前时间) |
| public Date(long data) | 创建一个Date对象,表示指定时间(从计算机时间原点开始,过了指定毫秒后的时间) |
- 常用成员方法
| 方法名 | 说明 |
| :------------------------------: | :--------------------: |
| public long getTime() | 获取时间对象的毫秒值 |
| public void setTime(long time) | 设置时间,传递毫秒值 |
SimpleDateFormat类
SimpleDateFormat可以对Date对象,进行格式化和解析
格式化:Date对象 \==\=\=》 2021年1月1日 00:00:00
解析:2021年1月1日 00:00:00 \===\=》 Date对象
常用的模式字母及对应关系
y ----- 年 M ----- 月 d ----- 日
H ----- 时 m ----- 分 s ----- 秒
2021-01-01 00:00:00 ------------- yyyy-MM-dd HH:mm:ss
构造方法
方法名 | 说明 |
---|---|
public SimpleDateFormat() | 构造一个SimpleDateFormat,使用默认格式 |
public SimpleDateFormat(String pattern) | 构造一个SimpleDateFormat,使用指定的格式 |
成员方法
方法名 | 说明 |
---|---|
public final String format(Date date) | 将日期格式化成日期/时间字符串 |
public Date parse(String source) | 从给定字符串的开始解析文本以生成日期 |
JDK8时间类
JDK8新增日期类
Date分为LocalDate、LocalTime、LocalDateTime
LocalDate 表示日期(年月日) 2021年11月11日
LocalTime 表示日期(时分秒) 11:11:11
LocalDateTime 表示日期 + 时间(年月日时分秒) 2021年11月11日 11:11:11
LocalDateTime类
LocalDateTime创建方法
方法名 | 说明 |
---|---|
public static LocalDateTime now() | 获取当前的系统时间 |
public static LocalDateTime of(年,月,日,时,分,秒) | 使用指定年月日和时分秒初始化一个LocalDateTime对象 |
LocalDateTime获取方法
方法名 | 说明 |
---|---|
public int getYear() | 获取年 |
public int getMonthValue() | 获取月份(1-12) |
public int getDayOfMonth() | 获取月份中的第几天(1-31) |
public int getDayOfYear() | 获取一年中的第几天(1-366) |
public DayOfWeek getDayOfWeek() | 获取星期 |
public int getMinute() | 获取分钟 |
public int getHour() | 获取小时 |
LocalDateTime转换方法
方法名 | 说明 |
---|---|
public LocalDate toLocalDate() | 转换为一个LocalDate对象 |
public LocalTime toLocalTime() | 转换为一个LocalTime对象 |
LocalDateTime格式化和解析
方法名 | 说明 |
---|---|
public String format(指定格式) | 把一个LocalDateTime格式化成为一个字符串 |
public LocalDateTime parse(准备解析的字符串,解析格式) | 把一个日期字符串解析为一个LocalDateTime对象 |
public static DateTimeFormatter ofPattern(String pattern) | 使用指定的日期模板获取一个日期格式化器Date TimeFormatter对象 |
LocalDateTime增加或者减少时间的方法
方法名 | 说明 |
---|---|
public LocalDateTime plusYears(long years) | 添加(正数)或者减(负数)去年 |
public LocalDateTime plusMonths(long months) | 添加或者减去月 |
public LocalDateTime plusDays(long days) | 添加或者减去日 |
public LocalDateTime plusHours(long hours) | 添加或者减去时 |
public LocalDateTime plusMinutes(long minutes) | 添加或者减去分 |
public LocalDateTime plusSeconds(long seconds) | 添加或者减去秒 |
public LocalDateTime plusWeeks(long weeks) | 添加或者减去周 |
public LocalDateTime minusYears(long years)
减去或添加年,和上边方法相反- 还有其他和上述方法类似的减去或添加方法
LocalDateTime修改方法
方法名 | 说明 |
---|---|
public LocalDateTime withYear(int year) | 直接修改年 |
public LocalDateTime withMonth(int month) | 直接修改月 |
public LocalDateTime withDayOfMonth(int dayOfMonth) | 直接修改日期(一个月中的第几天) |
public LocalDateTime withDayOfYear(int dayOfYear) | 直接修改日期(一年中的第几天) |
public LocalDateTime withHour(int hour) | 直接修改小时 |
public LocalDateTime withMinute(int minute) | 直接修改分钟 |
public LocalDateTime withSecond(int second) | 直接修改秒 |
时间间隔类
Period类
方法名 | 说明 |
---|---|
public static Period between(开始时间,结束时间) | 计算两个“时间”的间隔 |
public int getYears() | 获得这段时间的年数 |
public int getMonths() | 获得次期间的月数 |
public int getDays() | 获得此期间的天数 |
public long toTotalMonths() | 获取此期间的总月数 |
Duration类
方法名 | 说明 |
---|---|
public static Durationbetween(开始时间,结束时间) | 计算两个“时间”的间隔 |
public long toSeconds() | 获得此时间间隔的秒 |
public int toMillis() | 获得此时间间隔的毫秒 |
public int toNanos() | 获得此时间间隔的纳秒 |
异常
异常:就是程序出现了不正常的情况。程序在执行的过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
注意: 语法错误不算在异常体系中
JVM的默认处理方案
如果程序出现了问题,我们没有做任何处理,最终JVM会做默认的处理
- 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
- 程序停止执行(哪里出现异常就在哪里停止程序的运行)
throws
格式:throws 异常类名;
注意:这个格式是写在方法的定义处,表示声明一个异常。
指告诉调用者,在调用的时候可能出现这样的异常,如果方法中没有出现异常,正常执行。如果真的出现了异常,则是交给调用者处理,若调用者没有处理,则最终还是交给JVM虚拟机处理。
如果声明的异常是一个运行时异常,那么声明的代码可以省略
如果声明的异常是一个编译时异常,则必须要在方法后面进行显示声明
throw
格式:throw new 异常();
注意:这个格式是在方法内,表示当前代码手动抛出一个异常,下面的代码不再执行了。
throw和throws的区别
throws | throw |
---|---|
用在方法声明后面,跟的是异常类名 | 用在方法内,跟的是异常对象名 |
表示声明异常,调用该方法有可能会出现这样的异常 | 表示手动抛出异常对象,由方法体内的语句处理 |
意义
- 在方法中,当传递的参数有误,没有继续运行下去的意义了,则采取抛出处理,表示让该方法结束运行。
- 告诉调用者方法中出现了问题。
try...catch...
格式
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
优点:可以让程序继续向下执行。
常见问题
- 如果try中没有问题,会把try中代码全部执行完毕,但不会执行catch内的代码
- 当try中出现问题,直接跳转到catch语句中,try下面的语句就不会再执行,当catch内的语句全部执行完毕,会继续执行下面代码
- 出现多个异常,就需要写多个catch语句。如果多个异常之间存在子父类关系,那么父类一定要写在下面。
异常的成员方法
方法名 | 说明 |
---|---|
public String getMessage() | 返回此throwbale的详细消息字符串 |
public String toString() | 返回此可抛出的简短描述 |
public void printStackTrace() | 把异常的信息输出在控制台(红色字体) |
两种处理异常方式小结
抛出 throw throws
- 在方法中,当传递的参数有误,没有继续执行下去的意义了,则采取抛出处理,表示让该方法结束运行
- 告诉调用者出现了问题
捕获 try...catch...
- 能让代码继续运行下去
案例:键盘录入数据
// 需求:
// 键盘录入学生的姓名和年龄,其中年龄为18-25岁
// 超出这个范围是异常数据不能赋值,需要重新录入,一直录入到正确为止
public class ExceptionDemo{
public static void main(String[] args){
Student s = new Student();
Scanner sc = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = sc.nextLine();
String name = sc.nextLine();
while(true){
System.out.print("请输入年龄:");
String ageStr = sc.nextLine();
try{
int age = Integer.parseInt(ageStr);
s.setAge(age);
break;
}catch(NumberFormatException e){
System.out.println("请输入一个整数");
continue;
}catch(RuntimeException e){
System.out.println("请输入一个符合范围的年龄");
continue;
}
}
System.out.println(s);
}
}
// Student类
public class Student{
private String name;
private int age;
public Student();
public void setName(String name){
this.name = name;
}
public void setAge(int age){
if(age >= 18 && age <= 25){
this.age = age;
}else{
throw new RuntimeException("年龄超出了范围");
}
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
自定义异常
- 目的:为了让异常信息更加见名知意
步骤
- 定义异常类
- 写继承关系
- 完善构造方法(空参/有参)
推荐阅读:【JavaSE】集合进阶