总结
一.常用的API
1.Object 上帝类
1.1 object 常用方法
//获取对象hash值 ------hashCode() int code = t.hashCode();//2093631819 System.out.println(code); //将对象信息变为字符串返回 --------toString() System.out.println(t.toString());//day08Api.Test@7cca494b String s1 = "aaa"; String s2 = "bbb"; //判断两个内存地址是否一样 -----------equals() System.out.println(s1.equals(s2));//fasle //获取类名 --------getClass() System.out.println(t.getClass());//class day08Api.Test
2.String 字符串
-
1 String构造方法
/* public String() public String(byte[] bytes) public String(byte[] bytes,int offset,int length) public String(char[] value) public String(char[] value,int offset,int count) public String(String original)*/
2.2 String 常用方法
isEmpty() | 判断是否为空 | boolean |
---|---|---|
length() | 取到该String的长度 | int |
equals(Object obj) | 判断两个字符串是否相等 | boolean |
equalsIgnoreCase(String as) | 不区分大小写比较 | Object |
charAt(int index) | 返回该下标的char | char |
substring(int start) | 截取字符串下标从start开始 | String |
substring(int start,int end) | 截取区间字符串从start开始到end结束(包头不包尾) | String |
replace(char old,char new) | 替换字符串 | String |
trim() | 去掉字母首尾空格 | String |
System.out.println("判断当前字符串是否为空:"+str1.isEmpty());//false System.out.println("判断两个字符串是否相同:"+str1.equals(str2));//false System.out.println("不区分大小写比较:"+s3.equalsIgnoreCase(s4));//true System.out.println("字符串的长度为:"+str1.length());//4 String trim = str2.trim();//去掉收尾空格 System.out.println("去掉收尾空格之后的trim字符串为:"+trim); System.out.println("从指定开始索引截取到最后"+str1.substring(2));//万叶 System.out.println("截取指定范围字符串,包头不包尾"+s3.substring(2,4));//cd System.out.println(str1.charAt(0));//枫
2.3String类的型转换功能
getBytes() | 转换成bytes型数组 | byte[] |
---|---|---|
toCharArray() | 转换成char型数组 | char[] |
String valueOf(char[] chs) | 将入参类型转换为String | String |
toLowerCase() | 将所有英文字母转换为小写字母 | String |
toUpperCase() | 将所有英文字母转换为大写字母 | String |
concat(String str) | 将指定字符串连接到此字符串的结尾 | String |
2.4 String注意事项
String是一个用final修饰过的引用数据类型,他的值一旦创建便不能修改。
每次操作字符串都会创建一个新的字符串对象,为了优化字符串内存,一般采用StringBuffer/StringBuinder对字符串进行操作
2.5 Stringbuffer
StringBuffer是用来解决String更改字符串造成的时间浪费和空间浪费的
2.6 StringBuffer的常用方法
方法名 | 作用 | 返回值 |
---|---|---|
append(String str) | 追加字符串 | StringBuffer |
insert(int offset,String str) | 指定位置追加字符串 | StringBuffer |
deleteCharAt(int index) | 删除下标处的字符 | StringBuffer |
delete(int start,int end) | 删除下标区间的字符 | StringBuffer |
replace(int start,int end,String str) | 替换区间字符 | StringBuffer |
reverse() | 反转字符串 | StringBuffer |
substring(int start,int end) | 截取区间字符串从start开始到end结束(包头不包尾) | String |
substring(int start) | 截取字符串 | String |
3.包装类
3.1基本数据类型对应的包装类
int--------------Integer short--------------Short byte--------------Byte long--------------Long
float--------------Float double--------------Double char--------------Character boolean----------Boolean
3.2 Integer 的常用方法
parseXXX()类型转换,可以转换成对应的数据类型
方法名 | 作用 | 返回值 |
---|---|---|
intValue() | 转换成int | int |
parseInt(String s) | String转换成int | int |
valueOf(String s | String转换成Integer | Integer |
3.3Character 的常用方法
isUpperCase(char ch) | 判断指定字符是否为大写字母 | boolean |
---|---|---|
isLowerCase(char ch) | 判断指定字符是否为小写字母 | boolean |
isDigit(char ch) | 如果字符串中只含有数字则返回True | boolean |
toUpperCase(char ch) | 将小写字符转换为大写 | char |
toLowerCase(char ch) | 将大写字符转换为小写 | char |
4.工具类 util
4.1 Math 类 -----------常用方法
方法--(最大值 - 最小值)+最大值
方法名 | 作用 | 返回值 |
---|---|---|
abs(int a) | 取绝对值 | int |
ceil(double a) | 返回最小值 | double |
floor(double a) | 返回最大值 | double |
max(int a,int b) | 取最大值 | int |
pow(double a,double b) | 求幂 | double |
random() | 随机数 | double |
round(float a) | 四舍五入成整数 | int |
sqrt(double a) | 求double值的正平方根 | double |
4.2 Date ------------------------常用方法
Date d = new Date(); long time = d.getTime();//将今天的时间转换为毫秒值 SimpleDateFormat spm = new SimpleDateFormat("yyyy-MM-dd"); Date parse = spm.parse(birthday); long birthdayTime = parse.getTime(); long day = (time - birthdayTime) / 1000 / 60 / 60 / 24; System.out.println("你来到这个世界已经"+day*24*60*60+"秒了吧!!!"); System.out.println("你来到这个世界上已经"+day+"天了"); System.out.println("不出意外的话你的年龄是:"+(int) Math.ceil((double)day/365)+"岁吧!,被我猜中了吧,傻蛋!!!"); }
4.3 Calendar --------------日历类
方法名 | 作用 | 返回值 |
---|---|---|
getInstance() | 获取日期 | Calendar |
get(int field) | 获取年/月/日/时/分/秒 | int |
add(int field,int amount) | 计算时间 | void |
set(int year,int month,int date) | 设置时间 | void |
4.4 Random --------------- 随机数类
nextInt() | 生产一个随机数 | int |
---|---|---|
nextInt(int n) | 生成一个0~n之间的随机数 | int |
二.集合
1.常见集合的规则
collection 集合元素是无序可重复的
list:集合元素是有序可重复的
set 集合元素 是 无序不可重复的
map 集合元素 是无序唯一不可重复的
包名+类名 ==== 完全限定名
2.ArrayList/HashSet常见的方法
add() 添加元素 add(index ,数据) get(index)获取元素 remove(index)删除元素 contains()判断集合中是否存在该元素
//List集合的特点:有序,可重复的 // Collection<User> coll = new ArrayList<>(); List<User> coll = new ArrayList<>(); Scanner sc = new Scanner(System.in); //利用循环输入姓名密码存入user for (int i = 0;i<3;i++){ User u = new User(); System.out.println("请输入第"+(i+1)+"位用户的姓名:"); u.setUname(sc.next()); System.out.println("请输入第"+(i+1)+"位用户用户的密码:"); u.setPwd(sc.nextInt()); //再把每一个用户放到coll集合中 coll.add(u); } //利用以下方式来遍历输出集合 //方式一:迭代器 Iterator<User> it = coll.iterator(); while (it.hasNext()) { //一个迭代器中只能使用一个next(),next的作用是拿出元素并向后移,指向空就会报错,没有元素异常 //经常使用以下方式来输出 //定义一个变量接受.next()的值 User u = it.next(); System.out.println("用户名是: ----"+u.getUname()+" 密码是:--- "+u.getPwd()); } //方式2:增强for循环: for (User u : coll) { System.out.println("用户名是: ----"+u.getUname()+" 密码是:--- "+u.getPwd()); } //方式3:lambda---foreach遍历集合 coll.forEach(new Consumer<User>() { @Override public void accept(User user) { System.out.print("用户名是---"+user.getUname()); System.out.println("密码是---"+user.getPwd()); } }); coll.forEach(u -> System.out.println("用户名是:"+u.getUname()+"------密码是:"+u.getPwd())); }
hashset代码
Scanner sc = new Scanner(System.in); //set集合的特点:无序,不可重复,自动去重复 Set<Integer> intSet = new HashSet<>(); intSet.add(1); intSet.add(1); intSet.add(1); intSet.add(1); System.out.println("intset的集合大小是"+intSet.size());//1 intSet.add(2); intSet.add(3); intSet.add(4); intSet.remove(2); Set<User> uSet = new HashSet<>(); for (int i = 0; i < 3; i++) { User u = new User(); System.out.println("请输入第"+(i+1)+"位用户的名字:"); u.setUname(sc.next()); System.out.println("请输入第"+(i+1)+"位用户的密码"); u.setPwd(sc.nextInt()); uSet.add(u); } //无序集合采用迭代器的方法获取集合元素 Iterator<User> it = uSet.iterator(); while (it.hasNext()) { User user = it.next(); System.out.println("用户名:"+user.getUname()+"密码:"+user.getPwd()); } System.out.println(); //可以采用增强for的方法去遍历集合 //自动拆箱 for (User u: uSet) { System.out.print(u.getUname()+" "+u.getPwd()); } System.out.println(); //还可以采用foreach的lambda方式进行遍历输出 uSet.forEach(new Consumer<User>() { @Override public void accept(User user) { System.out.println("用户名:"+user.getUname()+"密码:"+user.getPwd()); } }); System.out.println(); uSet.forEach(s -> System.out.print(s.getUname()+" "+s.getPwd())); } }
3.HashMap常见方法
.put(键,值) 一个键对应一个值 键值对
keyset()拿出键,类型是set集合
get(key) map中的值可以通过键可以拿到值
values(),拿出所有的值,得到一个collection集合
.remove()删除对应的值
代码示例
//map 是一个键值对应的集合,map里面的键是无序不重复唯一的,可以通过keySet()方法来获取存储map键的值; //map里面的值是无序可重复的,可以通过values()来获取map集合里面的值集合,collection (一般不建议使用) Map<Integer,String> map = new HashMap<>(); //map.put(键,值),往里面存放值 map.put(1,"张飞"); map.put(2,"刘备"); map.put(3,"关羽"); map.put(4,"吕布"); map.put(5,"貂蝉"); //map.remove()移除,通过()里面的键去移除对应的值 map.remove(3); System.out.println(map.hashCode());//3309368 Set<Integer> set = map.keySet(); //可以通过得到的键去遍历对应的值map.get(key) Iterator<Integer> it = set.iterator(); while (it.hasNext()) { Integer key = it.next(); System.out.print(" 键-----"+key+" 值----"+map.get(key)); } System.out.println(); //第二种方法 for (Integer i: set) { System.out.print(" 键-----"+i+" 值----"+map.get(i)); } System.out.println(); //第三种方法: set.forEach(k -> System.out.print(" 键-----"+k+" 值----"+map.get(k))); }
4.底层原理
4.1ArrayList的底层原理
arrayList是一种线性数据结构,它的底层是用数组实现的,相当于动态数组。与Java中的数组相比,它的容量能动态增长。 当创建一个数组的时候,就必须确定它的大小,系统会在内存中开辟一块连续的空间,用来保存数组,因此数组容量固定且无法动态改变。ArrayList在保留数组可以快速查找的优势的基础上,弥补了数组在创建后,要往数组添加元素的弊端快速查找:在物理内存上采用顺序存储结构,因此可根据索引快速的查找素。
arraylist的自动扩容内存,. 容量动态增长: 当数组容量不够用时,创建一个比原数组容量大的新数组,将数组中的元素“搬”到新数组,再将新的元素也放入新数组,最后将新数组赋给原数组即可。
4.2HashMap的底层原理
put()首先把键值对封装到node对象当中,利用键的hashcode()得出hash值,通过哈希算法将hash值转成对应的数组下标,下标位置如果没有元素,就把这个键值对放到这个位置上,如果下标位置上有链表,拿着键链表上的每一个节点进行equals比较,比较完一轮返回的都是false的话,会被添加到链表的末尾,如果有一个equals返回了true,节点的value会被覆盖掉.
get()先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标,通过数组鼠标定义到一个位置上,如果这个位置上什么都没有返回null,如果有,则拿着对应的键跟链表上的节点进行equals,如果所有equals都返回false,则get方法返回null;,如果其中一个节点的k和参数k比较返回true,get方法会返回这个要找的value;
三.IO流
3.1 流
字节流 : InputStream 字节输入流 OutputStream 字节输出流
字符流 : Reader 字符输入流 Writer 字符输出流
在流实现后使用.close()进行关闭 (一般放在finally里面) ,在输出流实现后使用flush()刷新
.read()读取字节
.write()写入字节
.available()返回原文件大小
3.2代码示例
// 1. 创建输入、输出流对象 FileInputStream fis = null; FileOutputStream fos = null; try { long qian = System.currentTimeMillis(); // 2. 指定输入、输出的文件 fis = new FileInputStream("D://java黑马程序员//[Java参考文档].JDK_API_1_6_zh_CN.CHM"); fos = new FileOutputStream("G://文件转移//api.JDK_API_1_6_zh_CN.CHM"); // 3. 创建一个暂存读取数据的数组 byte[] x = new byte[1024]; // 4. 先读一下,并且将返回的读取长度保存在变量中 int leng = fis.read(x); // 5. 读取长度不等于-1代表还没读完 while (leng != -1){ // 6. 将读取回来的信息,写入到目标文件,从数组下标为0的地方开始写入,写leng长度 fos.write(x, 0, leng); // 7. 继续读 leng = fis.read(x); } // 8. 刷新缓冲区 fos.flush(); long hou = System.currentTimeMillis(); System.out.println(hou - qian); } catch (FileNotFoundException e) { System.out.println("这里有一个异常-----------------" + e.getMessage() + "-----------------"); } catch (IOException e) { System.out.println("这里有一个异常-----------------" + e.getMessage() + "-----------------"); } finally { try { // 1. 关闭链接 if(fos != null) fos.close(); if(fis != null) fis.close(); } catch (IOException e) { System.out.println("这里有一个异常-----------------" + e.getMessage() + "-----------------"); } }
四.SQL语句
1.新增 insert into 表名 values(),()
2.删除 delete from 表名 where 条件表达式
3.修改 update 表名 set 字段名 =值1 where 条件表达式
4.查询 select 字段名/(*) from 表名 where 条件表达式
-- where 条件分为 > < <> != = or and like limit between and in as inner/left/rghit join on
结构: where 条件运算符:> < = !=(<>) >= <= 逻辑运算符:&&(and) ||(or) !(not) 模糊查询:like(not like) between and in is null(is not null)
模糊查询 _ 代表代替一个字符 % 通配符
5.聚合函数
count() sum() max() min() avg()
格式: select 聚合函数(字段列表) from 表名;
6,分页查询 limit
select 字段名 from 表名 limit 起始索引,查询记录数
计算公式:起始索引 =(查询页码 -1) *每页记录数 查询页码为1,2,3,4,5
7.排序排序查询
语法 select 字段名 from表名 where 条件表达式 order by//(排序)按照某一个字段 asc 升序 desc 降序
8.连接
连接类型为 inner ----内连接 left ----左外连接 right---右外连接
select 查询列表 from 表1 [连接类型] join 表2 on 连接条件
where 筛选条件 group by order by
内连接 inner 左外连接 left [outer] 右外连接 right [outer] 全外连接
9.重命名 旧表名 [as] 新表名
起别名 select 100%98 as 结果;//as可以省略
10.去重 distinct --------------- select distinct 字段名 from 表名;
11.子查询是出现在其他语句内部的select语句
出现的位置: select后//支持标量子查询 from后//表子查询 where或者having //标量子查询、列子查询、行子查询 exists//相关子查询
按行列数不同分为:标量子查询(一行一列) 列子查询(一行多列) 行子查询(多行一列) 表子查询(多行多列)表子就是相关子查询
特点: 1.子查询在小括号内 2.在条件的右侧
12.SQL语句优化
Sql执行顺序
基础Sql优化
查询SQL尽量不要使用select *,而是具体字段
避免在where子句中使用or来连接条件
使用varchar代替char
尽量使用数值替代字符串类型
查询尽量避免返回大量数据
使用explain分析你SQL执行计划
是否使用了索引及其扫描类型
创建name字段的索引
优化like语句: 字符串怪现象 索引不宜太多,一般5个以内 索引不适合建在有大量重复数据的字段上
where限定查询的数据
避免在索引列上使用内置函数
避免在where中对字段进行表达式操作
避免在where子句中使用!=或<>操作符
去重distinct过滤字段要少 where中使用默认值代替null
高级SQL优化
批量插入性能提升
批量删除优化
伪删除设计
提高group by语句的效率
复合索引最左特性
排序字段创建索引
删除冗余和重复的索引
不要有超过5个以上的表连接 inner join 、left join、right join,优先使用inner join in子查询的优化 尽量使用union all替代union
16、关系数据
关系型数据库(SQL):存储的往往是字符、字符串、数值、布尔值等(存储在磁盘中)
关系数据库系统是基于关系模型的数据库系统,关系模型的数据结构使用简单易懂的二维数据表
每一行称为一条记录,用来描述一个对象的信息 每一列称为一个字段,用来描述对象的一个属性 1、关系模型可以用简单的“实体-关系-属性”来表示,称为:E-R图
1.1 实体
也称实例,对应显示世界中可区别与其它对象的“事件”或“事物”,如银行客户、银行账户。
1.2 关系
实体集之间对应关系称为联系,也称为关系。如:银行客户和银行账户之间存在“储蓄”的关系
1.3 属性
实体所具有的的某一特性,一个实体可以有多个属性,如“银行客户”实体集中的每一个实体具有姓名、住址、电话等属性。
-
start transaction;//开启事务
中间写多个SQL
commit;//提交事务
注意:中间的SQL不会立即执行,等到commit统一执行(保证原子性)。可以使用rollback主动进行回滚,恢复之前的状态。
事务四大特性
事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,要么同时成功,要么同时失败,有一条语句失败,就进行事务回滚,所有sql语句执行失败
开始控制事务 start transaction/begin
提交事务(成功) commit
回滚事务(失败) rollback
1)原子性
一个事务是一个整体,不可以分割。
2)一致性
事务执行的前后,数据都是合法状态。
3)持久性
数据库操作都是针对于硬盘,产生的效果就具有持久性。
4)隔离
并发访问数据库,事物之间隔离
17.索引
索引相当于书的目录,可以提高查的速度。但是索引也提高了增删改的开销,因为进行增删改会需要调整已经创建好的索引目录,降低增删改的速度。索引还提高了空间的开销。
三大范式:
1.不可拆分 (每列的原子性)(拆列)
-
每张表只能满足一个事情(拆表)
-
保证列与列之间不存在依赖关系