1.关于String类和Stringbuffer,StringBuilder的区别:
String:
此类有较多重载的构造器,常用的有String(),String(String original),String(char [ ] a),String(char[ ] a,int startIndex,int count),String(byte[ ] a)等等。实现了Serializable串行化接口,可以进行网络传输;实现了Comparable接口,可以调用接口中compareTo方法进行字符串大小比较。String类声明时是final类,因此不可继承。其有一private final char value[ ]私有成员变量用于存储字符串内容,由于此成员变量修饰符为final,所以一经赋值后指向的地址不可再变。 直接把字符串常量赋值给String对象的话,该对象指向的是常量池中该字符串地址,池中若无,则在其中创建该常量并让String对象指向它。例如String name = "xiaoming"。如果是使用new创建,例如String name = new String("xiaoming"),则在堆中开辟一块内存,栈中对象指向堆中的地址,堆中对象的value属性存放的是常量池中该常量的地址,如无就创建该常量。
- 常用方法:
- equals用来判断字符串内容是否相等并且区分大小写;
- equalsIgnoreCase也是判断字符串内容是否相等但是不区分大小写;
- length是用来获取字符串长度;
- indexOf获取字符第一次出现的索引,如果没有该字符则返回-1;
- lastIndexOf获取字符最后一次出现的索引,如果没有返回-1;
- substring(自然数)是截取该自然数索引以后的字符序列;
- substring(自然数1,自然数2)截取自然数1索引到自然数2索引(不包括自然数2的索引)之间的内容;
- concat用拼接字符串;
- replace("字符串1","字符串2")把所有的字符串1都替换成字符串2,注意是将返回后的结果替换,并不是调用了就替换;
- split("字符")以某个字符作为分隔符对原字符串进行分割;
- toCharArray将字符串转化为字符数组;
- compareTo比较两个字符串大小,前面的字符串大就返回正数,否则返回负数,相等返回0;
- format格式化字符串,类似于C语言中的输出函数,%s表示String类型,%d表示整数类型,%f表示浮点类型,%c表示字符类型;
StringBuffer:
是长度可变的字符序列,能够对字符串内容进行增删.实现了Serializable接口,CharSequence接口,继承了AbstractStringBuilder类,此类又实现了Appendable接口.在其父类中有一属性char value[ ],不是final类型,用于存放字符串的内容,存放于堆中.StringBuffer类用final修饰,所以不能被继承.此类和String类的区别在于,String类保存的是字符串常量,而StringBuffer类存放的是字符串变量,因此每次更新String类对象的内容时都要重新指向一个新的地址,效率很低.而String Buffer里面的内容可以随便更改,地址依旧不变直到超出存储范围,效率较高. 每当创建新的StringBuffer对象时,会调用无参构造方法创建一个初始容量为16的char value[ ]数组来存放字符串内容.
常用方法:
- append(),在字符串后面追加字符串,最终返回的依旧是StringBuffer类的对象;
- delete(index1,index2)删除索引范围在[index1,index2)之间的字符;
- replace(index1,index2,"字符串")使用字符串替换索引范围从[index1,index2)之间的字符;
- indexOf("字符串")返回字符串第一次出现的索引值;
- insert(index,"字符串")在索引为index的地方插入字符串,处于此处的字符后移;
- length()返回整个字符串的字符长度,是整数值;
//String转化为StringBuffer
String name = "xiaoming";
StringBuffer sb = new StringBuffer(name);//这里的sb对象才是真正的StringBuffer对象,并且对原来的String对象没有影响
//也可以调用append方法实现
StringBuffer sb2 = new StringBuffer();
sb2 = sb2.append(name);
//StringBuffer转化为String
StringBuffer sb3 = new StringBuffer("xiaoming");
//调用StringBuffer的toString方法
String s = sb3.toString();
//直接使用构造器
String s2 = new String(sb3);
StringBuilder:
由于该类方法没有使用synchronized修饰,所以不是线程安全的.该类用在字符串缓冲区被单个线程使用的时候,运行时速度较StringBuffer类要快,如是单线程,建议优先使用.该类继承关系和实现的接口与StringBuffer类相同.此类有修饰符final,故不可被继承.
总结:当字符串需要大量修改时,单线程使用StringBuilder,多线程使用StringBuffer.如果字符串不需要或者很少修改时,使用String类创建对象.
2.八种基本数据类型和包装类:
基本数据类型 | 包装类 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
装箱:基本类型---->包装类型; 拆箱:包装类型---->基本类型
注意:自动装箱的本质是Integer.valueOf(i),其中i是int i;自动拆箱的本质实际上是Integer的对象去调用intValue方法。补充:valueOf这个方法源码有一个判断,如果参数范围在-128~127之间,则不需要new Integer()即新建对象,具体返回的是cache数组里-128~127的一个具体值,那么可知integer x=3;integer y=3 中x和y属于同一个对象。而integer x=128;integer y=128 中的x和y不是同一个对象。
int i=0;
Integer integer = i;//自动装箱
int j = integer;//自动拆箱
3.try-catch,finally的作用:
在try中执行代码,如果有异常则跳出try语句块,并且不执行try语句块中出现异常之后的代码,转向catch块获取异常信息.若没有异常则顺序执行try语句块里面的代码,而不执行catch块的语句.finally语句块无论代码是否发生异常最终都要执行,常用来关闭链接和释放资源等.把有可能会抛出异常的代码用try-catch语句块包裹起来,当代码出现异常抛出异常信息,整个程序依旧会执行下去. 注意:当需要捕获多个异常时,子类异常一定要放在父类异常前面,否则编译器会报错.
异常有编译时异常和运行时异常.编译时异常有FileNotFoundException,ClassNotFoundException等,出现编译时异常时必须用try-catch或者throws来捕获异常,否则程序无法编译.常见的运行时异常有NullPointerException,ArrayIndexOutOfBoundsException等.出现此类异常如不处理系统默认使用throws方式抛出异常,可能是方法的调用者.
throws和throw的区别:throws抛出的是异常类,throw抛出的是异常对象.前者可以抛出多个异常类型,后者只能抛出一个异常对象.前者可能并不会出现真正的异常,后者则是必定有异常的处理.前者跟在方法名后,后者定义在方体中.
public class Exception{
public static int fun(){
try{
String names[] = new String[3];
if(names[0].equals("xiaoming")){ //names[0]为null,调用方法时抛出空指针异常
System.out.println(names[0]);
}
else{
return 1;
}
}
catch(NullPointException e){
return 2;
}
finally{
return 3;
}
}
public static void main(String []args){
System.out.println(fun());//输出结果为3,无论是否捕获异常,都会执行finally语句块.
}
}
4.MySQL常用语句和联表查询:
//SQL执行顺序
SELECT 字段名/函数
FROM 表名 //第一步
WHERE 条件 //第二步
GROUP BY 字段/函数 //第三步
HAVING 分组条件 //第四步
ORDER BY 排序行为 //第五步
//MySQL基础篇
//AS起别名
SELECT 字段 As 别名; //as 可以直接省略,使用空格隔开即可.如果别名是特殊符号,例如out,put,#等,需使用双引号将别名括起来
//DISTINCT查询去重信息
SELECT DISTINCT 字段 FROM 表;//使用关键字distinct筛选掉重复的信息
//CONCAT拼接字段名(中间添加其他符号需要用单引号引起来)
SELECT CONCAT(字段一,字段二) AS 别名 FROM 表;//有些字段为null,拼接之后整体为null,使用IFNULL(字段名,0)来解决
//like用法(%通配符表示任意长度任意字符,_占位符占据一位字符)
SELECT * FROM 表名 WHERE 字段 LIKE '%a%';//查询表中字段中间含有a的字段的所有信息
//in的用法
SELECT 字段名 FROM 表名 WHERE 字段 IN(字段具体值1,字段具体值2,字段具体值3);
//is NULL用来判断字段内容是否为空
SELECT 字段名 FROM 表名 WHERE 字段 IS NULL; //找出内容是null的字段,相反的话使用is not null
//排序查询(order by支持单个字段,多个字段,表达式,函数,别名)
SELECT 字段名 FROM 表名 WHERE 筛选条件 ORDER BY ASC/DESC; //ASC为升序排序,DESC为降序排序
//常见函数
//length()用于获取字段字节长度,utf-8中汉字占3个字节,英文字符占用一个字节.gbk中汉字占俩字节
SELECT LENGTH("字段名"); //打印出的数字为9
//UPPER,LOWER
SELECT UPPER("tom"); //打印结果为TOM
//SUBSTR()
SELECT SUBSTR(字段名,2) FROM 表名; //截取表的该字段中的第2个字符和之后的字符,元素起始索引为1
SELECT SUBSTR(字段名,1,5) FROM 表名; //截取表的该字段中的第1个和第5个之间的字符(包括1和5)
//INSTR()
SELECT INSTR("hello,world",'lo') AS nihao; //输出结果为4,在左边字段中找出右边字符第一次出现的索引值,如果找不到,则返回0
//TRIM()不加参数时是去掉字段前后的空格,加参数FROM则是去掉字段前后相同参数的字符.
SELECT TRIM('11' FROM ' 1111111nihaoya11111') AS nihao;//输出结果为 1nihaoya1
//LPAD()/RPAD()左填充和右填充
SELECT CONCAT(LPAD('nihao',9,'55'),RPAD('wohao',9,'66')) AS jieguo;
//jieguo为5555nihaowohao6666
//REPLACE()
SELECT REPLACE('wohenhaoya','h','g') AS output;//output为wogengaoya
//数学函数和日期函数
//ROUND()四舍五入
SELECT ROUND(3.145,2) AS output;//output为3.15
//CEIL()/FLOOR()向上/下取整
注意:CEIL()返回大于等于参数的最小整数,FLOOR()返回小于等于参数的最大整数
SELECT CONCAT(CEIL(1.2),'和',FLOOR(-1.2)) AS output;//output为2和-2
//TRUNCATE() 截断小数后面的其他位数
SELECT TRUNCATE(1.282828,1) AS output; //output为1.2
//MOD()
SELECT MOD(5,2); //输出为1
//STR_TO_DATE()将字符通过指定的格式转化为日期
SELECT * FROM users WHERE pubtime=STR_TO_DATE('3-14 2022 15:25 11','%c-%d %Y %i:%s %H');
//%Y指四位年份,%c指具体月份,%d指天数,%i指分钟数,%s指秒数,%H指小时数
//DATE_FORMAT()将日期格式化为指定字符串
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日');//输出当前年月日
//流程控制函数
SELECT IF(FALSE,'1','2');//输出为2,结构类似于条件运算符
SELECT bid ,zprice 总工资,
CASE bid
WHEN 13 THEN zprice*2
WHEN 14 THEN zprice*3
ELSE zprice
END AS 结果
FROM salary;//输出的部门号为13的工资乘2,为14的工资乘3,其他的为原工资
SELECT zprice 工资信息,NAME 姓名,
CASE
WHEN zprice<10000 THEN 'A'
WHEN zprice>=10000 AND zprice<=20000 THEN 'B'
WHEN zprice>20000 THEN 'C'
ELSE 'D'
END AS 工资等级
FROM salary; //输出为工资小于10000的为A,10000到20000之间为B,20000以上为C
//分组查询GROUP BY()
SELECT DATEDIFF(MAX(pubtime),MIN(pubtime)) FROM salary;//输出结果是最大日期和最小日期的天数差
SELECT MAX(age),cid
FROM users
GROUP BY cid; //通过cid分组,选出组中年龄最大的并显示年龄
//having用法
SELECT COUNT(*),cid
FROM users
GROUP BY cid
HAVING COUNT(*)>=1; //通过cid分组,查询每组个数大于等于1的cid号
//分组查询中的筛选条件分为两类:
数据源 所处位置 关键字
分组前筛选 原始的表 GROUP BY字句之前 WHERE
分组后筛选 分组后结果集 GROUP BY字句之后 HAVING
//GROUP BY和HAVING都支持别名,GROUP BY后面也可跟着表达式或者函数
//连接查询
//笛卡尔乘积发生的原因是没有建立有效的连接,数据量=m*n(m和n分别为俩表的数据行)
SELECT NAME,tname FROM dept,users
WHERE dept.id=users.cid; //添加条件即可避免笛卡尔乘积,也叫等值连接
SELECT NAME,tname FROM dept d,users u
WHERE d.id=u.cid; //也可以通过起别名的方式
//三表连接
SELECT uname 用户名,d.name 部门,f.name 职位
FROM users u,dept d,ftype f
WHERE u.cid=d.id AND u.zid=f.id;//查找表中用户对应的职位和部门信息
//等值连接的特点:
1.多表等值连接的结果为多表的交集部分;
2.N个表连接至少需要N-1个连接条件;
3.多表的顺序没有要求;
4.使用时最好起别名,比较方便;
5.可以搭配之前学过所有的子句一起使用.
//非等值连接
SELECT zprice,grade_level
FROM salary s,salary_grades sg
WHERE zprice BETWEEN sg.lowest_sal AND sg.highest_sal
AND sg.grade_level='B'; //查找薪资等级在这范围之间的且等级为B的薪资和等级
//自连接
在同一张表里存在可查找关系,通过别名的方式把一张表区分成两张表使用.
//SQL99语法
//内连接(INNER [OUTER] JOIN ) 包括等值连接,非等值连接,自连接
SELECT 查询字段
FROM 表1 别名
INNER JOIN 表2 别名
ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段
HAVING 分组条件
ORDER BY 字段 排序条件
SELECT uname,d.name,f.name
FROM users u
INNER JOIN dept d
ON u.cid=d.id
INNER JOIN ftype f
ON u.zid=f.id; //筛选出用户对应的部门名和职位名(等值连接)
SELECT zprice,grade_level
FROM salary s
JOIN salary_grades sg
ON zprice BETWEEN sg.lowest_sal AND sg.highest_sal
WHERE sg.grade_level='B'
ORDER BY zprice DESC; //筛选出工资在此范围并且工资等级为B的信息,并按照工资大小降序排序
(非等值连接)
//外连接
//应用场景:用于查询一个表中有,另一个表中没有的记录
//外连接结果=内连接结果+主表中有而从表没有的记录
//左外连接(LEFT[OUTER]JOIN)左边的是主表
SELECT uname,d.name
FROM users u
LEFT OUTER JOIN dept d
ON u.cid=d.id
WHERE u.id<=18 AND d.id IS NULL; //查询用户ID<=18并且部门为NULL的用户名和部门名
//全外连接=内连接结果+表1中有的表2中没有的+表2中有的而表1中没有的(FULL [OUTER] JOIN)
//交叉连接使用SQL99语法实现了笛卡尔积的型式
SELECT 字段
FROM 表1
CROSS JOIN 表2; //输出的是表1乘表2的数据