常用API
Applicatein Programming Interface
JDK提供的各种工具类利用封装将特定的一系列功能进行类的打包
方法四要素
方法名+功能
方法所属的类型
方法的参数列表
方法的返回值
Object
所有对象的最高级父类 里面存储的方法 所有子类都可以重写
boolean equals(Object) == 比较地址
int hashCode()对象的地址信息通过特定的哈希算法 获得的int类型数据
所以理论上说 地址不同 哈希值 不同 ==>默认父类原始方法
如果没有重写该方法 则比较的是地址 如果重写了 则忽略地址 根据重写时勾选的属性值来重新计算哈希值
字符串类型就属于 重写了 hashCode()和equals()的类型 根据字符串的内容来计算哈希值 和判断是否相等
所以理论上说 内容不同的字符串 计算出的哈希值应该不同
但是有特例 “通话” “重地” .hashCode() 都是 1179395 所以还要借助于equals() 来比较字符
String toString()格式化输出对象地址信息
Class getClass()获取该对象所属类的字节码文件
char c = '中';//单字符 多字节
syso((int)c); //20013
syso("中".hashCode()); //20013
syso(Arrays.toString(s.getBytes()));//GBK 2个元素的数组[-42, -48] UTF8 3个元素的数组[-28, -72, -83]
char c = 'a';//单字符 单字节
syso((int)c); //97
syso("a".hashCode()); //97
syso(Arrays.toString("a".getBytes()));//[97]
单字节单字符
//(数字 英文 英文标点符号)
字符串的哈希值 字符串的字节值 字符的ASCII值 三者相同
"a".hashCode() Arrays.toString("a".getBytes()) (int)'a'
//[97]
多字节单字符
//(一个汉字 一个中文标点符号)
字符串的哈希值 字符串的字节值 字符的ASCII值
"中".hashCode() Arrays.toString("中".getBytes())) (int)'中'
//20013 //[-42,-48] //20013
多字节多字符 以下为utf-8编码集
String s2 = "中国";
System.out.println(s2.hashCode());//642672
System.out.println((int)'中');//20013
System.out.println((int)'国');//22269
System.out.println(Arrays.toString(s2.getBytes()));//[-28, -72, -83, -27, -101, -67]
String
String str = "ab";
String str1 = "ab";
syso(str==str1) //true
String str = "a"+"b";
String str1 = "ab";
syso(str==str1); //true
String str = new String("aa");
String str1 = str; //共享地址
syso(str==str1); //true
final String s = "a";
String str = s+"ab"; //如果时常量的连接 是纯粹的值拼接
String str1 = "aab";
syso(str==str1); //true
//以下三种情况 有地址信息存在
String str = new String("ab");
String str1 = "ab";
syso(str==str1); //false
String str = input.next();//输入一个b 有地址产生
String str1 = "b";
syso(str==str1); //false
String s = "a";
String str = s+"ab"; //有变量的连接 有地址产生
String str1 = "aab";
syso(str==str1); //false
String构造方法
new String()==>有地址 不为Null===>可以调用方法 ==""
new String(String)
new String(char[])
new String(char[],int startIndex,int len)
new String(byte[])
new String(byte[],int startIndex,int len) 注意拼接的完整性
常用方法
null不能调用任何属性和方法 完全不同于"null" ==null
""有内容 有地址 可以调用属性和方法 String s = "";
字符串引用名 == null 先判断 为真 则不能调用任何属性和方法 否则 空指针
- 字符串引用名.equals("")
-
字符串引用名.length()==0 -
字符串引用名.isEmpty() 返回true 就是"" 返回false 说明有内容
boolean equals(Object) 忽略地址 判断字符
boolean equalsIgnoreCase(Object)忽略大小写 比较两个字符串是否相同
int length()
char charAt(int index) 下标 不能>=长度 不能<0
boolean isEmpty()没有内容 返回true 有内容 返回false
byte[]getBytes()将字符串 转为字节数组GBK一个汉字两个字节UTF8一个汉字三个字节 半角一个字节
char[]toCharArray()将字符串 转为字符数组
booleanstartsWith(String)判定是否以参数字符串开头
booleanendsWith(String)判定是否以参数字符串结尾
String[]split(String)将字符串按照参数切割成几个小字符串 并存入数组
StringString.join(String,String[])静态方法 将参数字符串数组 通过另一个参数拼接成新字符串
Stringtrim()去掉字符串两端的空格 input.nextLine()
StringtoUpperCase() 全转大写
StringtoLowerCase() 全转小写
StringreplaceAll(String old,String new)将字符串中 所有参数一替换为参数二
StringreplaceFirst(String old,String new)将字符串中【第一次】出现的参数一 替换为参数二
booleancontains(String)判断字符串中是否包含参数字符串
intcompareTo(String)如果返回值>0则调用该方法的字符串 在字母表后面 参数字符串在字母表前面
intcompareToIgnoreCase(String) 忽略大小写判断
重要方法
通过下标找元素
bear.png
Stringsubstring(int index)从参数下标开始 一直到末尾的字符串
Stringsubstring(int startIndex,int endIndex)从第一个参数开始 到第二个参数-1为止
通过元素找下标
*intindexOf(String)从左开始查找 返回参数字符串在原字符串中的起始下标
*intindexOf(String ,int startIndex)从第二个参数位开始向后查找 第一个参数出现的下标
×intindexOf(int)从左向右查找 参数表示的某个单字符的ASCII值
×intindexOf(int,int startIndex)从第二个参数位开始向后查找 第一个参数对应的字符串出现的下标
*intlastIndexOf(String)从右向左查找 参数字符串 第一次出现的下标
*intlastIndexOf(String,int startIndex)从第二个参数位开始向左查找 第一个参数出现的下标
×intlastIndexOf(int)
×intlastIndexOf(int,int startIndex)
练习
1.将录入的字符串首字母变大写 其余字母变小写 再判断是否以.class结尾 如果不是 则添加这个后缀
2.String str ="as23f#$g5AF$%Swa^6eFS%rq23wF4rad";
分别使用正向和逆向查找 查找出第二个a 出现的下标
统计字符串中 大写字母个数 小写字母个数 数字个数 特殊字符个数
//使用last方法 倒着找正向第二个a 出现的下标
String[] ss = new String[]{"bgasdf","bgjerr","uwer","uwet","yyure","yyzewr"};
String[] ss = new String[]{"yyzewr","yyure","uwet","uwer","bgjerr","bgasdf"};
用户输入一个新的全小写字母的字符串 插入到数组中合适的位置
cuuu
String 增强类
1.String是值不可改变的增强类的值是可变的
2.String 重写了equals() hashCode()增强类 没有重写这两个方法
3.StringBuilder线程非安全 效率高
StringBuffer线程安全效率低
没有重写hashCode() 和 equals()
因此 即使使用equals() 依然是判断的地址==》可以使用toString()转成字符串去比较
new StringBuilder(String)将字符串 通过构造方法 转为增强类
new StringBuffer(String)
String toString()将增强类转为字符串
StringBuilder/StringBufferinsert(int index,Object)将新内容插入到指定下标位
StringBuilder/StringBufferdelete(int start, int end) end表示删除下标位+1
StringBuilder/StringBufferreplace(int startIndex,int endIndex,String newStr)使用新字符串 替换下标间的老字符串 endIndex=真正的结束下标+1
StringBuilder/StringBufferreverse()将字符串倒置
StringBuilder/StringBufferappend(Object)增强类 不能使用+直接连接
正则表达式
主要是进行字符串的数据分析,java对此作了相应的改进。
* | 需要转译符 \\|
* ( 需要转译符 \\(
* a:表示匹配字母a
* \\匹配转义字符\
* \\t匹配转义字符\t
* \\n匹配转义字符\n
* \\*
*
* [a,b,c] 可能是a 可能是b 可能是c
* [^a,b,c] 不是a,b,c中任意一个
* [a-z,A-Z] 全部子母中的任意一个
* [0-9] 全部数字中的任意一个
* (xxx|xx|xxx) 三选一
*
* . 表示任意一位字符
* \d 等同于.[0-9]
* \D 等同于.[^0-9]
* \w .[a-zA-Z0-9]
* \W .[^a-zA-Z0-9]
*
* ? 0次或1次 {0,1}
* * 0次 1次 或多次 {0,}
* + 1次或多次 {1,}
* {n} 出现n次
* {n,} n次以上
* {n,m} n次到m次
案例
// String regex = "\\d{6,}";
// String pwd = "123456678";
// System.out.println(pwd.matches(regex));
// 数字 字母(多个) @ 数字 字母(多个) . com con cn
String regex1 = "[0-9,a-z,A-Z]+@[0-9,a-z,A-Z]+\\.(com|cn|con)";
Strint regex2 = "\\w+@\\w+\\.(com|con|cn)";
String s = "DFG@dfg.con";
System.out.println(s.matches(regex1));
// String r = "\\d{4}-\\d{7}";
// String zj = "1234-1234567";
// System.out.println(zj.matches(r));
1900-1999.1-12.1-30
//注意中括号和大括号之间的空格
String reg = "19[0-9][0-9]\\.([1-9]|1[0-2])\\.([1-9]|1[0-9]|2[0-9]|30)";
\\w+@\\w+\\.\\w+
邮箱 @ . 有且只有一个@ 和. @在.前面 不能以.结尾 例如 safWE1324@aFSdH23f.sdfRW123
Date
new Date()返回当前本机时间
new Date(long)返回从1970年1月1日0点 经过参数毫秒数之后的时间
new Date(String);"1900/03/03"
new Date(int year,int month,int date)返回参数定义的年月日时间年份-1900月份-1
new Date(int year,int month,int date,int hours,int minutes)
new Date(int year,int month,int date,int hours,int minutes,int seconds)
longgetTime()获取当前时间 距离1970年1月1日0点的毫秒数
System.currentTimeMillis()获取系统时间 距离1970年1月1日0点的毫秒数
intgetYear()要+1900
intgetMonth()要+1
...
SimpleDateFormat
Date d1 = new Date();
int year = d1.getYear();
int month = d1.getMonth();
int date = d1.getDate();
int hours = d1.getHours();
int minutes = d1.getMinutes();
int seconds = d1.getSeconds();
int day = d1.getDay();
System.out.println((year+1900)+"年"+(month+1)+"月"+date+"日"+" "+hours+":"+minutes+":"+seconds+" 星期"+day);
//1.设定标准
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss 周u");
//2.使用标准
String format = sdf.format(d1);
System.out.println(format);
//2.准备字符串
String str = "1999-4-3 17:22:15 周3";//ParseException
//3.调用方法 转回Date类型
Date d2 = sdf.parse(str); //该方法需要抛出一个ParseException异常
System.out.println(d2);
练习
获取一年前的今天 的 日期对象 使用字符串标准格式化输出
输入自己的出生年月日 获取其对应的日期类对象输出
计算自己活了多少毫秒 换算为xx天
正则表达式验证密码是否合法 密码由数字 字母组成 必须是6位
正则表达式验证日期是否符合要求 要求日期在190001-199912
LocalDateLocalTimeLocalDateTime
LocalDate ld = LocalDate.now();// 获取对象
ld = ld.of(1999, 5, 12);
System.out.println(ld);
System.out.println(ld.getDayOfMonth());
System.out.println(ld.getMonthValue());
System.out.println(ld.getYear());
LocalTime lt = LocalTime.now();
lt = lt.of(20, 22, 12);
System.out.println(lt);
//Date使用的是 SimpleDateFormat 格式.format(Date日期)
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("HH时mm分ss秒");
String times = lt.format(dtf1); //时间对象.方法(格式作为参数)
System.out.println(times);
// System.out.println();
// // 将LocalDate对象 转为字符串
// // 1.定义格式
// DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 E");
// // 2.使用格式
// String str = ld.format(dtf);
// System.out.println(str);
System.out.println();
String str1 = "1997-07-01";// 必须4位 2位 2位 只能-//DateTimeParseException
LocalDate newld = LocalDate.parse(str1); // 不是用定义的规则 直接通过本类静态方法
System.out.println(newld);
String str2 = "20:07:18"; //2位:2位:2位
LocalTime lt1 = LocalTime.parse(str2);
System.out.println(lt1);
String s3 = "2020-01-20T08:19:22";
LocalDateTime ldt1 = LocalDateTime.parse(s3);
System.out.println(ldt1);
Math
通过提供的【静态方法】 完成计算功能
返回形参相同类型abs(数值类型)获取参数的绝对值
doublerandom()产生一个随机小数 [0,1)例如:0.0 0.000005 0.99999 0.0235
doubleceil(double)向上取整无论小数点后是什么数字 (除0以外) 都会向大的方向+1
doublefloor(double)向下取整无论小数点后是什么数字 都直接去除 变为0 向小的方向
longround(double)四舍五入如果参数是负数 走 五舍六入
doublepow(double a,double b)计算a的b次方
doublesqrt(double)对于参数进行开平方
案例
double num = Math.random();
System.out.println(num);
int l = (int)(num*10);
System.out.println(l/3);
System.out.println(Math.ceil(-5.9));//向大取整
System.out.println(Math.floor(-5.01));//向小取整
System.out.println(Math.round(5.5));//四舍五入
System.out.println(Math.round(-5.5));//负数 五舍六入
int r = 3;
double s = Math.PI*Math.pow(r, 2);
System.out.println(s);
System.out.println(Math.sqrt(10));
DecimalFormat
DecimalFormat df = new DecimalFormat("#.###"); //0.00
String str = df.format(8.3456789);
System.out.println(str);//8.346
DecimalFormat df1 = new DecimalFormat("#.##%");
String str1 = df1.format(8.3456789);
System.out.println(str1); //834.57%
包装类
八大基本数据类型 对应的 引用数据类型
byteByteparseByte(String)
short Short parseShort(String)
intIntegerparseInt(String)
long LongparseLong(String)
float FloatparseFloat(String)
double DoubleparseDouble(String)
boolean Boolean parseBoolean(String)
char CharactercharAt(index)
String str = "345";
int num = Integer.parseInt(str);
syso(num); //整数类型 345
装箱 基本数据类型==》包装类
拆箱包装类==》基本数据类型
int num = 10;
Integer i = new Integer(num); //装箱
System.out.println(i);
int nums = i.intValue(); //拆箱
System.out.println(nums);
Integer i2 = num; //自动装箱
int num2 = i2; //自动拆箱
和String类型的转换
String str = "555";
int num = Integer.parseInt(str);//NumberFormatException
包装类 用来约束集合存储数据的类型
ArrayList names = new ArrayList(); //默认都是Object类型
names.add("张三");
names.add(123);
names.add(true);
ArrayList<String> names = new ArrayList<String>(); //使用包装类来约束类型
ArrayList<Integer> ages = new ArrayList<Integer>();
18.没有方法可以调用 因为默认int
Integer i = 18;
i.使用方法
异常类
JDK中提前为一些可能的错误 创建了一个类 当触发该错误时 会创建该类的对象 进行展示错误信息
架构
【Throwable】
【Error】错误
StackOverflowError
【Exception】【编译期异常】
ParseException
【RuntimeException】【运行时异常】
NullPointerException
IndexOutOfBoundsException
StringIndexOutOfBoundsException
ArrayIndexOutOfBoundsException
运行时异常
不影响编译运行的时候才可能触发的异常
1.绝对不可能出现不做任何处理
2.有概率出现该异常try catch 如果暂时不想处理 可以throws向后抛 后续处理
编译期异常
不处理 就无法通过编译
1.绝对不可能出现throws方案 绕过虚拟机向后抛出异常 暂时不处理
2.有概率会出现该异常try catch
throws
向后抛出异常 将异常的解决时机滞后 并没有真正的处理掉异常
写在出现异常的方法 参数列表 后面 后续可以跟多个【异常类名】没有顺序性
某个方法抛出了【编译期异常】 则调用它的方法 必须抛出一样 或者父类异常
继承关系中 如果子类重写的方法抛出【编译期异常】 则父类 或者 接口类 对应方法 必须抛出该异常或更高级异常
某个方法抛出了【运行时异常】 则调用它的方法 可抛可不抛
try catch
方法体内
try{
怀疑会出现错误的代码
}catch(异常变量名 Exception e){
//当try模块中的代码 抛出了异常对象 就会去下面的各个catch进行匹配
//匹配成功 则进入对应代码块进行执行不会再继续向下匹配
//当有多组catch模块时 要将小异常类型放前面 大异常放后面
}catch(ParseException e){//报错
//作为【编译期异常】 必须在try模块中的代码 有可能会报出该异常 才能catch 否则报错
}finally{
//无论程序是否正常执行 都一定要执行的代码 放入该模块
}
public class Pet{
public void show(){
}
public void show1() throws Exception{
}
}
public class Cat extends Pet{
//重写父类的show()
public void show() throws NullPointerException,IndexOutOfBoundsException,ArrayIndexOutOfBoundsException{
//子类随便抛出运行时异常 父类该方法 无需操作
//通过throws 抛出的异常 不分先后顺序
}
//重写父类的show1()
public void show1() throws ParseException{
//子类抛出了编译期异常 则要求 父类(接口类)的该方法要抛出相同或者更高级的异常
}
public void show2(){
try{
//可能出现运行时异常的代码 绝对不会出现ParseException
}catch(StringIndexOutOfBoundsException e){
//子类异常放前面
}catch(IndexOutOfBoundsException e){
//父类异常放后面
}catch(ParseException e){//报错
//不能随便catch编译期异常 必须是try内部的代码有可能触发这个编译期异常 才能catch
}catch(Exception e){
}
}
public void show3(){
try{
String str = null;
syso(str.length()); //NullPointerException
}catch(ParseException e){ //报错
//如果try内的代码 并没有可能出现该编译期异常 则不能catch该异常
}
}
}
public class Util{
public void start() throws ParseException,Exception{
Cat cat = new Cat();
cat.show();//该方法抛出的都是运行时异常 因此 调用时可不做操作
cat.show1();//该方法抛出了编译期异常ParseException 则调用这个方法的方法 也就是start()必须抛出一样 或者更高级的父类异常 或者 直接使用try catch处理掉 则start()也可以不做抛出
}
}
1.throws 只是为了绕过虚拟机的编译检查(并没有解决掉该异常)
场景:只能用在绝对不会触发的编译期异常
功能:向后抛出异常 将异常的处理时机滞后
语法特点:
1.可以向后抛出任何多个异常(运行时 编译期 都可)
2.没有子父类顺序要求
3.后期调用该抛出编译期异常的方法 的方法也必须抛出一样或更高级的编译期异常
4.对于编译期异常 如果子类重写方法抛出了编译期异常 则父类原始方法必须抛出相同或更高级编译期异常
2.try catch 真正的处理掉异常 代码可以继续向下执行
场景:只要有可能触发
功能:解决掉异常 给与友好提示 程序继续执行
语法特点:
1.尝试执行try模块内的代码(应该将怀疑会报错的代码放在其中)
2.如果没有报错 跳过以下所有catch 向后执行
3.如果报错 则创建这个异常类的对象
去依次匹配后续的catch 进入对应的catch模块执行
没有匹配的catch 直接报错 程序终止
4.执行完毕后 会跳出try catch模块 继续执行代码后续业务
5.对于编译期异常 try中有可能出现 才允许catch
6.后续catch模块中的异常 必须从小到大排列
throws:1.抛出异常类型2.没有顺序性3.无论是否可能出现 什么异常都可抛4.子类重写方法 抛出了编译期异常 则父类原始方法 必须抛出一样 或者更高级的异常 5.方法A调用了抛出编译期异常的方法B 则方法A必须抛出同样或者更高级的异常 或者使用trycatch处理掉这个异常
try catch:1.小扩号放入异常引用名 2.先放子 再放父3.对于编译期异常 必须有可能出现 才catch
练习
测试类中 有一个数组String[] names = {"","","",null,null};
判断是否有元素是 "张三" 使用try catch处理
判断用户输入的是不是 张三
自定义异常
1.定义异常类
编译期异常extendsException
运行时异常extendsRuntimeException
2.使用异常类
throw抛出一个异常对象就是犯错误 处理方案 与官方异常一样
案例
当用户输入的不是张三 或者 密码不是123 请用自定义异常的形式 提示用户 ”用户名或密码输入有误“
public class LoginException extends RuntimeException / Exception{
public LoginException(String message){
super(message);
}
}
//测试类
String name = "李四";
String pwd = "123";
if(!name.equals("张三")||!pwd.equals("123")){
//通过if找到抛出异常的时机
try{
//触发异常
String str = null;
syso(str.length());//会去查找空指针异常
throw new LoginException("用户名或密码有误");
}catch(NullPointerException e){
syso("没有对象");
}catch(LoginException e){
syso(e.getMessage());
}catch(Exception e){
syso("父类异常放最后");
}
}
syso("后续业务");
练习
1.定义一个编译期异常 LengthException 当访问一个数组不存在的下标时 抛出该异常 提示 不存在该元素
2.定义一个编译期异常 StrLengthException extends LengthException
父类Pet中 show(String str)
子类Dog中 重写show(String str)
如果str长度大于5 则使用 throw关键字报出StrLengthException 要求暂时不处理
测试类中 创建子类对象 调用show() 并处理该异常
评论