网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
概述:在代码运行过程中,一个名字表示的值可以发生变化
格式: 数据类型 变量名 = 变量值
说明: 数据类型:用来表示给变量在内存中分配多大的内存空间
变量名:给值起一个名字 =: 赋值符号
变量值: 需要存储或者保存的数据
使用变量的原因: 在程序中,有一些具有特殊含义的数据可以不断的发生变化,比如年龄,身高,体重,这些可以发生改变的数据。如果通过一个常量来表示不合理
这些可以发生变化的数据,可以通过一个不变的名字来表示,以后需要变化时,可以修改变量中的数据值
定义一个变量的过程,其实就是在内存中分配一段空间的过程 给变量赋值的过程,其实就是往空间中存值得过程 使用变量的过程,其实就是获取空间中存储值的过程 改变值的过程,其实就是将空间中的值替换的过程
变量是有作用域的: 作用域:起作用的范围 在哪一个大括号中定义变量,就只能在哪一个大括号中使用这个变量 变量在同一个作用域中不能重复定义,不能重名 变量必须先赋值后使用,变量定义和赋值可以分为两行去完成 如果需要定义多个相同数据类型的变量,可以在一行定义
数据类型
java语言是一个强类型语言,在定义一个变量或者数据时,需要强制的给这个变量指定分配多大的内存空间数据类型就是决定给一个变量分配多大空间的作用
整数的默认类型 int类型 4字节 随便定一个整数,默认为int类型 如果需要表示一个很大的整数,可以在整数的后面加一个L,不会认为int默认为long
小数的默认类型: double类型 8字节 随便定义一个小数,默认为double类型 如果需要表示一个单精度的小数,可以在小数的后面加一个大写的F,默认float
- 基本数据类型
官方定义的一些关键字,是有限个,用来给基本常量定义空间的含义 基本数据类型中存储的都是数据本身
+ 整数类型
- byte
1字节 -128-----127
-2^7---2^7-1
- short
2字节 -2^15----2^15-1 -32768----32767
- int
4字节 -2^31----2^31-1 -2147483648----2147483647
- long
8字节 -2^63----2^63-1
+ 小数类型
- float
4字节 单精度 >8字节的long
- double
8字节 双精度 >4字节的float
+ 字符类型
char 2字节 0----65535
+ 布尔类型
boolean true/false
- 引用数据类型
可以是自己创建的一些类型,是不固定个数的,引用数据类型中存储的不是数据本身,而是数据的地址值
字符类
字符常量:使用单引号引起来的单个符号 char
计算机只可以识别二进制的数字 0和1组成,每一个字符都可以对应一个十进制的整数,将这个十进制的整数,再通过对进制的转换,将十进制转为二进制,计算机可以识别
每一个字符和每一个整数对应的关系,称为编码表或者字符集
字符到数字是编码 数字到字符是解码
- char
字符串类
使用双引号引起来的一系列字符 字符串对应的数据类型string 字符串类型不仅可以表示一个变量,也可以和其它类型的数据进行+计算:不是加法运算而是拼接 如果字符串类型和其他类型的数据+,先将其他类型的数据转为字符串类型再拼接
-
String
- equal(参数)
比较两个字符串是否一样
- equalsIgnoreCase(参数)
忽略大小写比较是否一样
- isEmpty()
判断调用者字符串是否为空
- contains(参数)
判断调用者字符串是否包含参数字符串
- startsWith(参数)
判断是否以参数开头
- endsWith(参数)
判断是否以参数结尾
- substring(int i,int j)
截取参数中的内容
- substring(i)
从指定的位置开始往后截取 位置都从0开始
- toUpperCase()
将调用者转为大写
- toLowerCase()
将调用者转为小写
进制
概念:对信息或者数据进位的一个制度
转换有一个关系:计算的规则 系数*基数的权次幂再相加 说明 系数:各个位上的值是多少系数就是多少 基数:当前这个书是几进制,基数就是几 权:用来表示每位上的数字的一个重要程度的标志 从右往左依次递增,最小权0,从0往左依次递增
二进制转十进制 1100: 020+0*21+122+1*23
八进制转十进制 35: 5*80+3*81
十六进制转十进制 af: 1516^0 +1016^1
十进制转为其他进制 1计算的规则: 除基倒取余 2说明: 除:除法运算 基:要转为几进制,基就是几 取余:两个数相除的余数,反过来取,合在一起
十进制倒二进制 11 1100 0 l60**_** 0 l30**_** 1 l15 1 l7 1 l3**_** 1 l1 0
- 十进制
十进制:0-9 逢十进一
- 二进制
二进制:0和1 逢二进一
- 八进制
八进制:0-7 逢八进一
- 十六进制
十六进制:0-9abcdef 逢f(16)进一
运算符
概述:对数据做各种操作或者逻辑运算的符号
- 算术运算符
-
相加运算 字符串的拼接 表示正数 - 减法运算 表示负数
- 乘法运算 / 除法运算 如果两个数都是整数那么结果也是一个整数,求两个数的商 如果有一个是小数,那么结果也是一个小数 %取余运算符 取模运算符 取两个数相除的余数 结果的正负只和前面那个数的正负有关,跟后面那个数的正负无关
- 自增自减运算符
分类++ – 注意事项: ++和–就是表示变量本身加1或者减1 如果某个变量自增或者自减是单独作为一句存在时,++或者–放在变量的后面或者变量的前面没有任何区别,都是自加一或者自减一 如果某个变量自增或者自减不是单独作为一句存在,++或者–放在前面或者后面,计算方式不同: 符号放在变量的后面:先取值,后运算/ 符号放在变量的前面,先运算后取值
- 赋值运算符
分类 基础的赋值运算符:= 将右边的赋值给左边 扩展的赋值运算符:+= -+ *= /= %= 先将符号左右两边的值,先进行对应的运算,再赋值给左边
- 比较运算符
用来比较数据之间的关系。 比较运算符的结果只有两个: true false 分类 基础的比较运算符:
< >= <=(都只可以在数值之间比较 只能比较 整数 小数 字符) 扩展的比较运算符: ==(比较两边的数据是否一样) !=比较两边的数据是否不一样 注意事项: 可以在数值之间比较,也可以在字符串之间比较,或者布尔之间比较,但是不能不同类之间比较
- 逻辑运算符
1 概念:对表达式做一些逻辑的处理和判断 2 分类:& | ! && || 3 &:逻辑与 如果符号左右两边的表达式结果都为真,运算的结果为真 如果符号左右两边有一个结果为假,结果为假 4 |:逻辑或 如果符号左右两边的表达式结果都为假,运算结果为假 如果符号两边的表达式结果有一个为真,结果就为真 5 !:逻辑非 表达式的结果为真 取假 表达式的结果为假 取真 6 &&:逻辑短路与 左右两边的表达式结果为真,整个的结果为真否则为假 特点: 如果符号左边的表达式结果为假,右边的表达式不会执行,直接取假 如果符号左边的表达式结果为真,右边的表达式会执行,根据后面的取值 7 逻辑短路或 左右两边的表达式结果都为假,整个的结果都为假否则为真 特点: 如果符号左边的表达式结果为真,右边的表达式就不会执行,直接取真 如果符号左边的表达式结果为假,右边的表达式会执行,根据后面的取值
- 位移运算符
1概念:通过移动位数来表示数据的变化 2分类: << >> >>> 3 <:左移运算符 某个数据左移一位,扩大2倍 4>:右移运算符 某个数据右移一位,缩小2倍 即可以操作正数,也可以操作负数 5 >>>: 无符号右移运算 向右移动一位,缩小2倍 只可以操作正数,不可以操作负数
- 三元运算符
三元运算符,三目运算符 元:可以操作的数据或者表达式 三元运算符:可以操作三个数据或者表达式的符号 格式:表达式1?表达式2:表达式3; 逻辑 先执行表达式1,结果要么为真,要么为假 如果表达式1结果为真,执行表达式2,将表达式2的结果作为整个表达式的结果 如果表达式1结果为假,跳过表达式2,执行表达式3,将表达式3的结果作为整个表达式的结果 6 注意事项: 表达式1必须是一个布尔表达式,运算的结果为真,或者为假的表达式 表达式2和表达式3,只要有一个结果就行
键盘录入
在程序启动之后,可以让用户给变量输入一些数据,用户录入的结果是几,在代码中就使用几 步骤 导包:import java.util.Scanner; 创建对象:Scanner sc = new Scanner(System.in); 使用键盘录入的方法:int x = sc.nextInt(); 使用录入的x值 3.注意事项: 导包必须在类的上面导 nextInt方法表示需要录入一个数据,如果不录入就一直等待 录入之后的结果,可以做任何操作
获取随机数
在程序启动之后,可以获取一个数字 步骤 导包:import java.util.Random; 创建对象:Random r = new Random(); 调用方法获取值:int x = r.nextInt(); 使用获取的随机数x 3.注意事项; 如果没有指定的范围,默认的范围是int类型的范围 想要指定一个范围,在nextInt方法的括号中写入一个指定的数字k,范围就是0-k -1 方法的参数中只可以传递一个正数,不可以传递负数,如果想要表示负的范围,只能通过对应的运算来控制
流程控制
流程:在程序中用来表示代码执行的顺序 流程控制:控制代码执行的顺序就是流程控制
- 顺序结构
顺序结构:代码从上往下,从左往右依次执行(也是代码默认的执行顺序)
- 分支结构
分支结构:在代码执行的时候,可能碰到某种情况,情况的结果不同,可能执行不同的分支(代码写的多,执行的少)
+ if语句
1 if语句的第一种格式: if(条件表达式){ 语句体; } 2:执行流程 先执行条件表达式,结果要么为真,要么为假 如果结果为真,执行语句体 如果结果为假,不执行语句体 执行后面的其它代码
2 if语句的第二种格式 if(){ 语句体1; }else{ 语句体2; } 执行流程 先计算条件表达式的值,要么为真,要么为假 如果结果为真,执行语句体1 如果结果为假,执行语句体2
3if语句的第三种格式 if(条件表达式1){ 语句体1 }else if(条件表达式2){ 语句体2 }else if(条件表达式3){ 语句体3 } ...
else{ 语句体n; }
执行流程: 先执行条件表达式1 如果表达式1的结果为真,执行语句体1,直接结束if语句 如果表达式1的结果为假,判断条件表达式2 如果表达式2的结果为假,执行语句体2,直接结束if语句 如果表达式2的结果为假,往后继续判断条件表达式 如果后续的表达式结果为真,就执行对应的语句体,执行之后,结束if语句 如果表达式都为假,就执行else语句体n
+ if语句和switch语句的区别
if语句相对比较强大,可以对任何判断使用 switch语句做一些区间的判断比较麻烦,但是做一些离散型的匹配相对简单 如果使用if语句做一些离散的匹配,效率太低
+ switch语句
switch语句格式 switch(表达式){ case 常量1: 语句体1; case 常量1: 语句体1; break; ... default: 语句体n;
}
执行流程: 先执行表达式,获取表达式的值 判断获取的值,和常量1是否一样 如果一样执行语句体1,执行break,结束整个switch语句 如果获取的值和常量1不相等,将值和常量2判断是否一样 如果值和常量2相等,就执行语句体2,执行break,结束整个switch语句 如果值和常量2不相等,继续往后匹配其它常量,有一样的就执行对应的语句体,执行break结束 如果匹配没有一个相等的,就执行语句体n;
switch语句注意事项 表达式的结果必须是以下几类:byte short int long string 枚举类型(enum) case后面只可以定义常量,不可以定义变量 break表示中断,执行break就直接结束整个switch语句,如果不添加break,直接执行后面的内容,发生case穿透 default语句表示默认的情况,可以加也可以不加:::如果加,至少能执行一句;如果不加,可能一句执行不到 default语句可以放在switch语句的前面,后面或者中间,不管放在什么位置,都是最后去匹配,如果放在前面或者中间的话,需要在语句体的后面加上break,防止发生穿透
- 循环结构
如果某些代码需要反复的执行,可以使用循环结构的格式,来完成代码的简化
+ for循环
格式 for(初始化语句 ; 条件表达式 ; 初始化变量的变化){ 循环体语句; }
说明: 初始化语句:一般声明一个变量用来记录从几开始,循环了多少次 条件表达式:循环何时停止何时继续,通过条件表达式来控制 初始化变量的变化:让初始化变量进行变化 循环体语句:哪些代码需要反复执行,这段代码就是循环体语句
for循环注意事项 for循环后面不要加分号,一旦加上分号就不能控制循环体语句 循环体语句可以是任意操作 条件表达式必须是一个布尔表达式,必须获取一个真或者假 初始化变量的变化,可以是增加,可以是减少,但是一定要朝着结束循环的方向变化 如果循环体语句只有一句,可以省略大括号,如果有多久,也可以省略大括号,但是只执行第一句
+ while循环
1格式 初始化变量; while(条件表达式){ 循环体语句; 初始化变量的变化; }
+ do...while循环
1格式: 初始化变量; do{ 循环体语句; 初始化变量的变化; }while(条件表达式);
+ 死循环
1 概述:循环一直继续,无法停止 2 分类: for格式的死循环 for( ; ; ){ 循环体语句; }
```
while格式的死循环
while(ture){
循环体语句;
```
}
3 注意事项 死循环的后面不能写任何其他语句,因为死循环无法停止,后面的语句无法执行,编译报错 一般使用while的死循环
4 为什么是用死循环 当编程的时候不知道什么时候要停止,没有一个结束的标志时,可以使用死循环,当需要停止的时候,可以用跳转语句结束死循环。 服务器的设计中,一般也会用到死循环
+ 跳转语句
概述:用来结束循环的几个关键字 分类: continue; 结束本次循环,继续下一次循环 break; 结束break所在的那一层循环 return; 结束方法 System.exit(0); 结束虚拟机
+ 嵌套循环
在一次循环中,循环体语句又是一个循环 格式 for( 初始化语句1; 条件表达式1 ; 初始化变量1的变化){ for( 初始化语句2; 条件表达式2 ; 初始化变量2的变化){ 循环体语句; } }
特点: 外层循环的条件表达式控制外层循环的次数 内层循环的条件表达式控制内层循环的次数 外层循环循环一次,内层循环循环初始化变量2控制的次数 整个循环结束的标志是-----条件表达式1结果为假
方法
1 概述:就是可以完成某一段功能的代码段 2 原因:如果有一些代码以后经常使用,可以将这段代码通过一个大括号括起来,然后再给这个大括号起一个名字,以后想要使用这段代码,只需用这个名字即可
3 好处 提高代码复用性 可以提高数据的安全性,提高封装性 可以降低代码的复杂程度
- 方法的定义
1 格式 修饰符 返回值类型 方法名称 (参数列表){ 方法体; return语句;
}
2 说明: 修饰符:统一先写为:public static 返回值类型:方法既然是一个功能,就有可能有数据的产出,这些产出的数据是什么类型,返回值类型就定义为什么类型 方法名称:给代码段起一个名字。小驼峰命名法 参数列表:方法是一个功能,要像让方法完成指定的功能,就有可能要提供一些资源,资源就通过参数列表来定义 方法体:用来完成功能的具体逻辑代码 return语句:将产出的数据进行返回,返回给调用者
- 方法的调用
1 格式: 方法名(参数); 2 分类: 直接调用:直接使用方法名即可;当方法没有数据的产出时,只需要调用方法名即可 输出调用:直接将方法的调用写在输出语句中即可;方法有返回值,只需要去展示或者输出一次,就可以使用这种方式 赋值调用:使用一个变量将方法返回的结果进行接收;如果返回值以后会多次反复使用,使用赋值调用
总结: 不调用就不会执行 如果方法定义中需要一些参数(资源),在调用时就要传递对应的实际参数的数据
- 方法的注意事项
1 方法的定义: 方法之间是平级关系,不能嵌套定义 方法可以使用嵌套顶用(可以在一个方法中,使用另一个方法) 方法定义的先后,没有任何区别,先试用哪一个,就先执行哪一个 2 参数列表 形式参数:在定义方法时,带着数据类型的变量,用来接收以后传递的真实数据 实际参数:在使用方法时,传递的一些具体的数据 (1)实际参数和形式参数是对应的 (2)多个形参或者实参,中间使用逗号分隔
3 return语句 结束方法;返回参数 return后面跟着的数据的数据类型要和返回值类型保持一致 如果方法没有返回数据,将返回值定义为void,也可以将return语句写为return; 或者省略不写 谁调用方法,返回的数据就返回给谁 return语句一定是在最后
- 栈内存
栈内存的特点 方法先进后出,后进先出 一次同时只能执行一个方法
- 方法的重载
1、Overload 重载 2 、概述:在同一个类中,多个方法的方法名相同,参数列表不同,与返回值类型无关 3、说明: 在同一个类中:重载只能在一个类中发生 方法名相同:多个方法的名字一模一样,大小写也一样 参数列表不同:参数的数量不同,参数的类型不同,参数的类型顺序不同 与返回值无关:判断方法之间是否重载,不要考虑返回值类型
4、使用重载的原因 如果没有重载:在一个类中,定义了多个具有相同功能的方法,需要给不同的方法取不同的名字,后续再调用的时候考虑是用哪一个名字,这样做麻烦 如果有重载:在一个类型,需要定义多个具有相同功能的方法,可以给这些方法起一个相同的名字,以后只需要使用一个名字调用即可,在调用的时候,具体调用哪一个方法,根据传递的参数列表来区分
数组
- 数组的概述
用来存储相同数据类型的一个容器,这个容器有规律的存放数据
- 数组的定义
数据类型[] 数组名称 = new 数据类型[长度]; 数据类型 数组名称[] = new 数据类型[长度];
数据类型:表示当前数组中用来存放哪一类数据 []:表示一个一维数组 数组名称:给数组起一个名字 =:赋值符号 new:表示一个关键字,用来创建的意思 [长度]:表示当前数组中可以存放多少个数据
- 数组的初始化
数组的初始化就是给数组分配空间并赋值 分类 有动态初始化和静态初始化 动态初始化:、 数组的定义 : 数据类型[] 数组名称 = new 数据类型[长度]; 数组的赋值:数组名称[索引] = 元素值; 注意事项:动态初始化定义数组之后,如果数组中的位置没有赋值会有一个默认值 int:0 , double:0.0 ,char:‘’,String:null,boolean:false
静态初始化:格式 数据类型[] 数组名称 = new 数据类型[]{元素值的罗列}; 简写格式 数据类型[] 数组名称 = {元素值的罗列};
- 数组的内存
注意事项:虽然两个数组等号后面的内容相同,但是一旦碰到new关键字,就需要重新开辟第二段数组空间,并不是指向同一个数组
两个引用指向同一个数组: 引用表示地址 指针
引用数据类型的变量:用来存储数据地址的变量
两个引用指向同一个数组: 其中一个引用修改了数组中的内容,另一个在引用访问时,数据是修改之后的,两个引用可以访问一个数组,访问相同的一些数据
+ jvm
java虚拟机执行java语言的容器
+ 分类
- 栈内存
栈内存:执行方法的区域。先进后出,后进先出
- 堆内存
用来存放大量数据的区域。数组对象
- 方法区
用来执行或者存放字节码对象的区域
- 本地方法区
本地方法区:java虚拟机加载系统资源的区域
- 计数器/寄存器
用来给cpu分配空间的
- 数组的异常
数组异常:在操作数组的时候,遇到的各种问题
+ 数组索引越界异常
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
原因: 访问了不存在的索引
+ 空指针异常
Exception in thread "main" java.lang.NullPointerException
原因:数组的地址为空,还要通过空地址访问数组中的元素
解决,在访问数组之间 , 先判断数组是否为空
-
数组的操作
- 数组的遍历
概述:将数组中的元素逐个获取 思路:通过循环获取数组中的每个元素的索引,再通过索引结合结合名称获取对应的元素
数组有一个自带的属性:数组名.length 获取数组长度的属性
- 数组的最值
思路:需要定义一个变量,用来存储最大值或者最小值,再逐个获取数组中的元素,两两进行比较,数据比较大的继续在变量存储,比完一轮之后变量中存的就是最大值 注意事项:在定义存储最大值的变量时,变量中不能定义为无关元素,需要定义成数组中的某一个元素
- 数组元素的交换
给ID能够两个所以,交换两个元素索引对应的元素 思路:声明一个第三方变量,用来交换
- 数组的反转
概述:将数组中的元素逆序存储
1:如何定义两个变量,一个从头开始,一个从尾开始,头部元素索引可以为0,尾部length-1 ,当交换两个元素之后,可以让0索引+1,让length-1-1,然后依次移动知道两者一样 2.如何交换两个对称的元素 可以声明第三方变量
- 数组元素的获取
概述:给定一个元素,查询该元素在数组中的位置(索引) 思路:先获取数组中的每一个元素,逐个要和查询的值进行比较,,如果相等,就保存该元素的索引,如果不等,就继续比较下一个,直到将每个元素比完为止
- 数组的排序
1排序:将数组中的元素从小到大或者从大到小进行排序 2冒泡排序:先遍历数组,再在遍历数组的时候判断比较大小 i 和 i+1 比较,设一个第三方变量
-
二维数组
二维数组:二维数组中的每一个位置存储的并不是数据本身,而是一个个一维数组的地址
动态初始化: int arr = new int3; 静态初始化: int arr={{0,1},{10,20},{2,3,4},null};
面向对象思想
概述:面向对象是java语言编程使用的一种解决问题的编程套路,是一个编程思路 面向过程和面向对象区别: 面向过程:注重解决问题的基本步骤,强调解决问题的过程;比如:碰到一个问题,要考虑每一步怎么去完成
面向对象:注重解决问题的主体,强调找一个主体去完成,比如:碰到一个问题,不需要考虑具体的步骤,考虑如何找到一个主体
面向对象和面相过程的具体关系 面向对象是更高一层的编程思想:面向对象是基于面向过程的,需要先有面向过程,才能有对象去使用
- 好处
可以减少代码的冗余量 可以降低代码解决问题的难度 由执行者变为了指挥着
-
特征
- 封装
概述:在客观世界中,每个人的属性都是私有的都是隐藏的,并不是信息都可以被随意 的访问。在java语言中每个类的属性应该也是私有的,应该是也隐藏的,如果满 足一定的条件才可以访问属性或者非法。
1. 封装的原则: (1)隐藏事物的属性和行为 (2)提供一些公共的访问方式3.好处 (1)提高数据的安全性 (2)也可以提高代码的复用性
封装属性和方法使用一个关键字 private:私有的 特点:可以使用该关键字修饰变量,修饰方法,修饰类型或者接口,修饰常量
效果:一旦属性和方法被private修饰之后,只可以在本类中被访问
000、一旦将属性封装之后,外界是不能随意的访问 所以需要给属性提供一些公共的访问方式 给属性赋值或者取值分别提供一个方法: 给属性赋值的方法:set方法 给哪一个属性赋值,方法名称就写为:set属性名 给属性取值的方法:get方法 取哪一个属性的值:方法名称为:get属性名
- 封装的优化 变量访问原则 1、就近原则: 在某个方法中,如果需要使用某一个变量 首先在当前方法中寻找,有没有该变量的定义,如果方法中有定义,就直接使用 如果在方法中没有该变量的定义,就去当前方法所在的类中寻找有没有定义,如果有定 义就使用,如果当前类中也没有该变量定义,就编译报错。 1、在定义变量时应该做到见名知意,但是给set方法的形参定义名字之后,不能给对象中 的属性赋值成功,因为有就近原则。 2、为了避免这个错误,就使用了this关键字,被this修饰之后的属性,就直接表示当前对 象中的属性。 3、this:当前对象 哪一个对象调用this所在的方法,this就表示哪一个对象
- 继承
1、概述:面向对象三大特征之一,让类和类之间产生子父类的关系 2、关键字:extends 3、子类:用于继承其他的类 派生类 4、父类:被其他类继承的类 基类 超类 5、继承的好处: (1)减少代码的冗余量 (2)提高代码的复用性 (3)提高代码的可维护性 6、缺点: 提高了类之间的耦合性 耦合性:类之间的关联 7、效果:子类继承父类之后,父类的一些内容,子类可以继承,可以使用
- 注意事项 1、父类中定义的私有变量和私有方法,子类不能继承 父类的私有成员变量,在子类中不能直接访问、使用 虽然父类的私有变量子类不能直接访问,但是可以使用继承而来的公共访问方法去 间接的访问。 2、父类中的构造方法,子类也不能继承 原因1: 父类的构造方法名字应该和父类的类名保持一致 子类的构造方法名应该和子类的类名保持一致 如果子类继承了父类的构造方法,那么子类的构造方法名就不能喝类名保持一致 原因2: 父类的构造方法是用于给父类的成员变量初始化赋值 子类的构造方法用于给子类的成员变量初始化赋值 如果子类继承父类的构造,子类中定义的特殊属性,就不能使用构造赋值 3、使用继承需要遵循两个原则: 程序员类:姓名 年龄 工资 工作 项目经理类:姓名 年龄 工资 奖金 工作 管理工作 ``` 原则1: 父类中应该定义的是一些公共内容 如果子类有特殊内容,可以在子类中单独定义 原则2: 子类必须是父类的一种 is a ``` - 成员关系 1、子类对象: 子类对象既可以访问父类中定义的成员变量,也可以访问本类的成员变量 2、父类对象: 父类对象可以访问本类的成员变量,不能访问子类的成员变量 3、注意事项: 如果子父类中定义了相同的成员变量,子类对象在访问的时候,根据就近原则访问 在使用某一个变量时,先去方法中寻找有没有定义,有就使用,没有就去当前类中寻找 有没有定义,有就使用,没有去当前类父类中寻找有没有定义,有就使用,没有就编 译报错 4、如果想要访问本类对象中的属性,可以使用this关键字修饰 如果想要访问父类对象中的属性,可以使用super关键字修饰 * this 1、this:当前对象,哪个对象调用this所在的方法,表示哪一个对象 this可以访问本类对象中的属性 this可以访问本类对象所属类型的方法 this()表示访问本类的构造方法 * super 1、super:当前对象中父类的对象 super可以访问本类对象中父类对象的属性 super可以访问本类对象父类对象所属类型的方法 super()可以访问父类的构造方法 - 子父类构造方法的关系 1、父类中的构造方法,子类可以继承? 父类中的构造方法子类不能继承,如果子类需要给父类中的私有成员变量赋值 不能直接调用父类中的私有成员变量赋值,但是可以调用父类的有参构造来赋值 2、目的: 子类对象在初始化本类的属性之前,需要先初始化父类的数据 (1)如果在子类的构造方法中,没有显示的调用任何其他构造,系统会默认在本类的 构造方法中提供一个super(); (2)如果在子类的构造方法中,显示的调用了父类的构造方法,系统不会提供默认的 父类构造了。 (3)如果在子类的构造方法中,显示的调用了本类的构造方法,系统也不再提供其他 任何构造。 * 注意事项 1、注意事项: (1)如果需要调用构造方法,不管是调用子类的构造还是调用父类的构造, 构造方法必须在第一行 (2)this访问构造和super访问构造,不能在一个方法中 (3)构造方法不能递归调用 递归就是方法自己调用自己 - 成员方法的关系 1、子类对象: 既可以访问本类的方法 也可以访问父类的方法(私有除外) 2、父类对象: 只能访问本类的方法,不能访问子类的方法 - 方法的重写 1、引入: 父类中定义了一个方法,子类需要这个功能,但是不想使用父类中定义的实现内容 2、解决: 可以正常继承父类的方法,但是可以将父类的内容进行修改,这就是方法的重写 3、重写: 在子父类中,方法的名字相同,参数列表相同,返回值类型也相同 方法体语句可以不同。 4、要检测一个方法是否是重写,可以使用一个注解: @Override 在重写的方法上加上注释,如果不报错,表示当前方法是重写的父类方法 如果加上注释之后,方法编译报错,表示此方法不是重写的 - 特点 1、特点:Java语言支持单继承,不支持多继承,支持多层继承 2、单继承:一个子类只能继承一个父类 (一个孩子只能有一个亲爹) 3、多继承:一个子类可以继承多个父类(不支持) 原因:如果一个类型继承多个父类,多个父类中有一些相同的方法声明,但是实 现内容不同,将来子类调用方法时不知道执行哪一个方法。 4、多层继承:A类继承B类 B类继承C类 C类继承D类 特点:多层继承之后,越往下继承,类型的功能越多
- 多态
概述:表示事物的多种状态
- 对象的多态性 一个对象可以有不同的引用来接收,可以使用不同的类型来表示 - 类型的多态性 一个类型将来可以有不同的子类来实现 一个类型的引用可以接收不同的子类对象 - 多态的前提 必须要有子父类的继承关系(接口和实现类的实现关系) 必须要有父类的引用指向子类的对象(接口的引用指向实现类的对象) - 目的 方法的重写 - 多态中访问成员变量 1编译看左边,运行也看左边 2如果需要访问某一个变量,在编译阶段就看=号左边的类型中,有没有该变量的定义,如果有就能编译成功 3运行某一个变量,看=左边的类型中如何给该变量赋值,左边类型如何赋值就如何使用 - 多态中访问方法 编译看左边,运行看右边 编译时期看左边的类型中有没有该方法的定义,有就编译成功,否则编译失败 运行时期看右边类型中,该类型如何对方法进行实现的,右边类型如何实现就如何使用 * 多态中访问静态方法 1、编译看左边,运行看左边 2、注意事项: (1)父类中定义的静态方法,子类可以继承,但是不能被重写 (2)如果子类中定义了一个和父类静态方法一模一样的声明,子类只能使用自己的静 态方法,父类继承的静态方法会被隐藏。 - 向上转型 使用父类的引用指向子类的对象 * 特点 不管是访问方法还是访问变量,都需要先编译看左边,父类中有定义才可以使用 本质:限定了子类对象的访问范围,只能使用父类中定义好的内容 - 向下转型 将指向子类对象的父类引用,恢复为子类的引用 格式: 子类引用 子类对象 = (子类类型)指向子类的父类引用 本质:恢复了子类对象的访问 - 动态绑定机制 动态绑定机制:使用多态访问方法时,先去父类对象中,发现父类对象属于某一个子类对象,然后就将访问的权限跳出到子类对象中,再去子类对象中访问此方法 - 多态的好处 1.提高代码的扩展性: 可以在某一个方法的参数列表中,定义一个父类的引用,将来可以接收任何子类的对象而且执行的结果也可以根据传入的子类对象,执行子列的特殊内容 - instanceof关键字 1、格式: 对象名 instanceof 类型 2、特点: (1)是一个二元运算符 (2)可以对一个对象进行判断,如果左边的对象属于右边的类型,结果为真 如果左边的对象不属于右边的类型,结果为假 3、作用: 避免向下转型的时候,出现类型转换异常
类和对象
- 类
类的定义,一个类型都无非是从两点进行定义和表示:
属性:表示当前类型的一些概括和介绍 在java语言中,都是通过一个个变量来定义定义变量和之前不一样,需要在类中方法外定义(成员变量)
行为:表示当前类型的一些功能,可以做哪些事情 在java语言中,通过一个个方法来表示行为和功能
表示类型的方法:修饰符
特点:不管是带着主方法的测试类还是非测试类,还是自己定义的类型也好,在编译之后都会生成一个对应名称的.class字节码文件
- 对象
1概述:对象表示某一个类型的实例,表示一个真实的事物,具体事物 2、创建对象的格式: 类型名 对象名 = new 类型名();
3、说明 创建哪一个类的实例,就写那一个类的名字 对象名:起一个名字 小驼峰 =:将右边的对象地址赋值给左边的对象名 new:关键字 创建对象的关键字 类型():构造方法
对象访问属性 对象名.属性名
对象属性赋值 对象名.属性名 = 值;
对象访问方法 对象名.方法名();
成员变量没有赋值可以有一个默认值: String:null 整数:0 小数:0.0 字符:’‘ 布尔:false
两个对象 注意事项 两个类型指向两个对象,之间互不影响 类型的字节码文件加载一次即可,后续需要反复使用,可以使用第一次加载的
两个引用指向同一个对象 两个引用指向同一个对象,其中一个引用将对象中的数据进行修改,另外一个引用访问的是修改之后的结果,因为两引用公用一个对象中的数据
+ 成员变量
在类中方法外定义的变量 在对象中创建空间,对象在堆内存中,成员变量在堆内存中 生命周期随着对象的创建而存在,随着对象的消失而消失(当没有引用指向内存中的对象时,对象会被垃圾回收机制回收掉) 成员变量有默认值
+ 局部变量
在主方法中定义的变量 在栈内存中分配空间存储值 随着方法的调用而存在,随着主方法的出栈而消失 局部变量没有默认值,必须先赋值才能使用
+ 匿名对象
再创建对象之后,不适用引用接收,就是一个匿名对象
格式: new 类型名();
使用场景: (1)如果类型中的某个方法,只需要调用一次,可以使用匿名对象调用 好处:可以少创建一个对象的引用,节约栈内存空间
```
(2)如果调用某个方法,方法需要接受一个对象,在调用方法时,可以创建一个匿名 对象直接传递。
好处:节约内存空间
(3)如果定义某一个方法,方法需要返回某一个对象,可以直接创建一个匿名对象进 行返回。
```
好处:解决内存空间
+ 静态
1、如果没有静态: 某个类型的每一个对象中,都有一个相同的属性值,就需要在每一个对象中给这个相同 的属性值,都开辟一段空间来进行存储。 弊端: (1)浪费内存空间 (2)如果需要修改这个相同的属性值,每个对象都需要进行修改,数据维护麻烦
2、有静态: 如果某个类型中的每一个对象中都有一个相同的属性值,可以将该属性定义为静态 一旦定义为静态之后,该静态变量就在方法区中开辟空间存储数据 好处: (1)解决堆内存空间 (2)如果需要赋值或者需要修改只需要操作一次即可,数据维护起来比较容易
- 特点
静态使用static关键字来表示 静态变量随着类的加载就存在 静态变量是在对象的创建之前就已经存在,可以被访问 某个类型中的静态变量可以被该类所有对象所共享 静态可以被类名直接调用,也可以被对象调用
静态方法的特点 通过static 修饰的方法就是一个静态方法 跟静态特点相同
- 注意事项
静态方法不能访问非静态变量,可以访问静态变量
静态方法随着类的加载就可以被调用,这时对象还没创建,非静态变量就还没有存在,就不能被访问
静态方法中,不能调用非静态方法 因为非静态方法可以访问访问非静态变量,如果静态方法可以访问非静态方法,就相当于静态方法可以间接地访问非静态变量
静态方法中不能存在this关键字 this表示当前对象,静态方法可以被调用的时候,对象可能还没有被创建,this不知道指向哪一个对象
总结:静态不能访问非静态
+ 静态变量
静态变量属于类,随着类的加载存在,在方法区中存储,生命周期随着字节码对象回收,可以通过类名调用,也可以通过对象调用
+ 非静态变量
非静态变量属于对象,在堆内存中存储,生命周期随着对象的创建存在,随着对象的回收消失,只能通过对象调用
构造方法
概述:在创建一个对象时,构造方法可以给对象中的属性初始化
别名:构造器 构造函数
格式: 修饰符 方法名(参数列表){ 方法体语句 } 说明: (1)修饰符:public (2)方法名:和类名一模一样 (3)参数列表:要和那些属性赋值,就定义那些变量 (4)方法体语句:给属性赋值的操作
特点: 构造方法是在创建对象时,由虚拟机默认调用 构造方法不能自己手动调用 一个对象只能调用一次构造方法
注意事项 1、如果类中没有定义任何构造方法,系统默认提供一个空参构造 2、如果在类中定义个任意一个构造方法,系统不再提供另外一个 3、一般在类中既要提供空参构造,也要提供有参构造(利用方法的重载) 如果在创建对象时,传递参数,就会默认调用有参构造给属性赋值 如果在创建对象时,不传递参数,就会默认调用空参构造
代码块
1、使用一对大括号括起来的代码都是代码块 代码块放在不同的位置,有不同的名称和不同的作用
- 局部代码块
1、概述:在主方法中定义的代码块称为是局部代码块。 2、作用: 限定变量的生命周期,随着代码块的结束,代码块中定义的变量会被回收 节省内存空间 3、注意事项: (1)在代码块中定义的变量,在代码块之外不能使用 (2)在代码块外定义的变量,在代码块中修改了变量的值,随着代码块的结束,变量 值是修改之后的。
- 构造代码块
1、概述:在类中方法外定义的代码块 2、特点: (1)在创建对象的时候,由虚拟机默认调用构造代码块 (2)构造代码块是在构造方法之前被调用 (3)构造代码块是随着对象的创建被执行,所以创建一次对象,构造代码块执行一次 3、作用: (1)可以给属性赋值 (2)可以将空参构造和有参构造的公同内容定义在构造代码块中
- 静态代码块
1、概述:在类中方法外定义的代码块 2、格式: static{
}
3、特点: (1)静态代码块是在类加载的时候,被虚拟机默认调用 (2)在对象创建之前就已经被执行 (3)静态代码块中可以访问静态属性,但是不能访问非静态 (4)静态代码块随着类的加载执行,所以在程序的执行过程中,一个类型只需要加载 一次,所以静态代码块只执行一次。 4、作用: (1)可以给静态变量赋值 (2)静态代码块中可以定义只需要加载一次的资源(加载驱动)
- 同步代码块
final关键字
1、概述:最终的,最后的 2、作用: 修饰类型 修饰方法 修饰变量 3、修饰类型: 一旦一个类型被final修饰之后,变为一个最终类,不能有子类 4、修饰方法: 一个方法方法被修饰之后,不能被重写,但是可以被子类继承 5、修饰变量: 一个变量被修饰之后,就变为了一个常量 常量必须等于某一个值,该常量的值也不能被修改 因此这个被fianl修饰的变量,就变为了一个符号常量(有名字的常量)
内部类
1、概述:将类型定义在方法的内部或者类的内部就是一个内部类 在方法A中定义个类型B,类型B就是一个内部类 在类A中定义一个类型B,类型B也是一个内部类
-
成员内部类
- 普通的成员内部类
1、概述:在类中直接定义一个不加任何修饰符的类型 2、特点: (1)内部类中,可以直接访问外部类的成员 (2)在外部类中,要想访问内部类的成员,需要创建内部类的对象才可以访问 (3)在其他类中,要想访问内部类的成员,需要先创建外部类的对象,然后需要再创建内部类的对象 (4)内部类的对象不能访问外部类的成员
- 私有的成员内部类
1、在类中定义一个内部类,类可以通过private修饰 2、特点: (1)在私有的成员内部类中,可以直接访问外部类的成员 (2)在其他类中,要想访问私有内部类的成员,不能直接通过外部类的对象去访问, 需要在外部类中提供一个访问私有内部类的公共的访问方法,通过公共的方法可 以访问私有内部类的成员
在类中私有内部类以外创建一个方法,在方法里创建私有成员内部类的对象(给私有的成员内部类提供一个公共的访问方式)
- 静态的成员内部类
1、概述:在类中定义一个内部类,内部类通过static来修饰 2、特点: (1)在静态的内部类中,不能直接访问外部类的非静态成员,如果需要访问外部类的 非静态成员,可以创建一个外部类的对象去访问。 (2)在静态的内部类中,可以直接访问外部类的静态成员 (3)如果需要在外部类中访问静态内部类的成员,需要分析要访问的成员是否是静态 的,如果要访问的成员是静态的,就不需要创建内部类对象,否则需要创建 (4)如果在其他类中,想要访问静态内部类的成员,不需要创建外部类的对象,只需 要创建内部类对象即可。 格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名(); (5)一个类型是否需要创建对象,跟当前类是否是静态无关,跟要访问的成员是否是 静态有关,如果要访问的成员是静态,就不需要创建对象,否则需要
-
局部内部类
1、概述:在主方法中定义的内部类 2、特点: (1)局部内部类不能定义为私有的或者静态的 (2)局部内部类中,可以直接访问方法中定义的数据 (3)局部内部类中,可以定义私有的和普通的成员,但是不能定义静态的成员 (4)局部内部类不能在其他方法中直接访问,需要在内部类所在的方法中提供对象和 访问方式 总结:只要是一个类型,在编译之后都会生成一个独立的.class文件
- 匿名内部类
1、概述:没有名字的类型 匿名内部类是属于局部内部类的一种 2、格式: new 父类类名(接口名){ 对父类或者接口方法1的重写 对父类或者接口方法1的重写 };
父类引用(接口引用) = new 父类类名(接口名){
对父类或者接口方法1的重写
对父类或者接口方法1的重写
};
3、使用场景: 如果只需要对接口或者父类中的抽象方法调用一次,可以匿名内部类方式创建一个匿名 对象来简化操作
包
1、概述:用来分类管理代码资源的文件夹,也可以参与编译器的编译 2、效果: 一旦给类型加上包之后,类的全类名发生变化: 全类名 = 包名 + 类名 3、作用: (1)分类管理类文件 (2)可以在不同包中起相同的类名 4、包的使用方式: (1)在使用一个类型时,如果在当前包中使用这个类型,直接写类名即可 因为首先会默认在当前包中寻找有没有该类,如果有就可以直接使用 (2)–如果在其他包中要使用某个类型,需要使用全类名 --如果反复的使用此类,每次都要将一个很长的名字进行书写,他复杂 --为了简化这个操作,可以使用导包语句来进行操作 --导包方式:import 要使用类的全类名 导包之后,可以在当前类中直接使用名字即可 (3)注意事项:可以使用*通配符将整个包中的类全部导入,但是不建议使用 5、包的命名方式: 在一个工程中,只要包是唯一的即可 一般都是全小写 6、声明包: 只要在某一个包中定义了一个类型,就需要在文件的第一行定义当前类在哪一个包下
权限修饰符
1、概述:用来修饰类型、接口、变量、等内容的一个修饰的符号
- private
只可以在本类中被访问
- 默认/空
可以在本类中直接访问 可以在本包的其他类中访问
- protected
可以在本类中直接访问, 可以在本包的其他类中直接访问 可以在其它包的子类中直接访问
- public
可以在当前工程中直接访问
抽象类
1、抽象:抽取相同的或者相似的内容
- 抽象方法
(1)只有方法的声明,没有方法的实现内容,为了表示这个方法是一个抽象方法,所 以使用一个关键字abstract修饰。 将来子类中都有自己的实现方式,父类中定义的实现内容不需要使用,所以就干 脆只定义一个方法的声明即可。
- 特点
1、可以定义抽象方法的类型就是一个抽象类,为了表示一个抽象类,也需要使用一个关键 字abstract来修饰。 2、抽象类和抽象方法的关系: 抽象方法必须在抽象类中定义 抽象类中可以不存在抽象方法 抽象类中既可以定义抽象方法,也可以定义非抽象方法 3、抽象类不能实例化(创建对象) 因为如果抽象类可以创建对象,就可以调用自己的方法 如果调用了抽象方法,那么没有实现内容去执行 4、抽象类子类的前途: 如果子类重写完父类中定义的每一个抽象方法,子类就变为一个普通类,可以正常创建 对象 如果子类没有重写完父类中定义的抽象方法,子类就只能定义为一个抽象类,不能创建 对象 5、虽然类型是一个抽象类,但是和其他类一样编译之后,形成一个独立的字节码文件
+ 抽象类成员特点
1、抽象类中既可以定义变量也可以定义常量,但是不能被抽象 因为定义的变量和常量名已经有一层被抽象的含义,所以不需要再进行抽象 2、抽象类中既可以定义抽象方法,也可以定义非抽象方法 如果定义了抽象方法,子类需要去重写 如果定义了普通方法,子类可以去继承 3、抽象类需要定义构造方法? 抽象类需要定义构造方法,因为抽象类有子类,子类需要访问父类的构造方法
- 模板设计模式
1、设计模式:Java程序员,解决问题,或者设计类型,设计代码所需要的一个编程套路。 2、模板设计模式:抽象类的一个应用: 如果一些类型中有一些相同的内容,可以将这些相同的内容抽取到抽象类中定义,不同 的内容也可以定义为抽象方法在父类中定义。相同内容可以让子类继承,不同内容可以 让子类重写。
接口
1、概述: 生活中的角度: 接口其实就是表示一类规则,想要使用某些事物,就需要满足规则所需要的要求, 否则就不能使用。 Java语言: 用来定义规则特殊类型 专门用来定义方法规则的特殊类型 专门用来定义抽象方法的特殊类型 2、好处: (1)接口本身表示一类规则,一旦将规则定义好之后,只需要按照接口中的规则实现 对应的功能即可。 接口可以降低类与类之间的耦合性。
- 定义
1、接口的定义:需要使用一个关键字 interface
- 接口和抽象方法的关系
1、接口和抽象方法的关系: (1)接口中只能定义抽象方法,如果不加abstract,接口可以默认提供 (2)不能定义非抽象方法
- 特点
1、接口本身不能实例化(创建对象) 2、接口没有子类,但是接口可以有实现类 (1)如果一个类型想要实现一个接口,需要使用implements (2)以后接口和类之间不是子父类的关系,而是接口和实现类的关系 (3)如果一个类型实现一个接口之后,这个类型中,就可以继承接口中的抽象方法
、接口在编译时候,同样会生成对应的字节码文件
+ 接口的成员特点
1、接口中不能存在变量,可以存在常量 接口中可以定义变量,但是默认加上public static final强制变为一个公共的静态常量 接口中可以定义常量,也会提供public static
2、接口中需要定义构造方法? 不需要。 因为实现类将来访问的是父类的构造方法,不需要访问接口的构造方法 因为接口中不能定义成员变量,就不需要给变量赋值,所以不需要定义构造
- 接口和方法的关系
1、接口和方法的关系: 接口中只可以定义抽象方法,用于让实现类去重写 接口中不能定义非抽象方法
- 接口的实现类前途
1、接口的实现类前途: (1)如果实现类重写了接口中的每一个抽象方法,就变为一个普通类 (2)如果实现类没有重写完每一个抽象方法,这个类就变为一个抽象类
-
类、接口互相的关系
- 类与类
1、类与类之间: 继承关系 extends 继承特点:可以单继承、不能多继承、可以多层继承
- 类与接口
1、类与接口: 实现关系 implements 实现特点:可以单实现,可以多实现,不可以多层实现 多实现:多个接口之间使用逗号分隔即可 实现了多个接口之后,多个接口的抽象方法,实现类都可以继承 如果多个接口中有一些相同的方法声明,实现类只需要重写一个即可 不可以多层实现:一个类型实现一层之后,那就是类与类的关系 一个实现类,可以在继承一个父类之后,可以同时实现多个接口
- 接口与接口
1、接口与接口: 继承关系 特点:可以单继承,可以多继承,可以多层继承 可以多继承:每一个父类的抽象方法,子类都可以继承 可以多层继承:最底层的子接口,可以拥有以上所有父类和间接父类的抽象方法
- 抽象类与接口
1、抽象类和接口的区别: (1)抽象类/类:一般定义物体本身固有的属性和行为 (2)接口:一般定义物体通过扩展或者学习得来的行为
jar包
- 定义
用来存放编译好的字节码文件的压缩包 是java语言专用的压缩包
- 为何定义
1)Java源代码在编译之后,会生成对应的.class文件,.class文件中包含了该类定义 的各种属性和方法,所以可以脱离源代码使用 (2)脱离源代码使用需要一定条件: 需要将.Class文件打成jar包 (3)如何生成jar包: (1)选中需要导出的文件,export -> java -> jar file->选择导出的位置,起一个名字即可 (2)生成的jar包是一个压缩包,里面就有选择导出的字节码文件 (4)如何使用jar包: (1)在当前工程下,创建一个文件夹 lib (2)将需要导入的jar包,直接复制到lib文件夹中 (3)选中导入的jar包,右键->build path->add to build path 当工程中,出现一个对应名称的奶油瓶,表示加载成功
- 类库
存放jar包的文件夹
+ 导入
(1)如何导入类库: 选中工程->build path->configure build path ->libraries->add libraries->选择需要导入 的类库-> apply
+ 删除
(1)删除类库: 选中工程->build path->configure build path ->libraries->选择需要移除的类库- >remove-> apply
API
API: Application Programming Interface 应用程序编程接口
- 应用程序编程接口
java官方定义了很多编译好的类型,要想使用这些类型,就需要借助帮助文档来学习类型的描述,所以说这个帮助文档就可以理解为是一个规范一个规则。
- 使用
1、 在线API文档:需要网络访问的应用程序编程接口 2、 离线API文档:下载后的应用程序编程接口 步骤: (1)索引 (2)输入框中输入需要查看的类型 (3)类型中,会有一个介绍和方法的展示等等
-
API的制作
- 概述
1、 概述:在一个类中,没有任何数据的维护,没有定义任何成员变量,类中定义的全都是一些静态方法。
- 作用
1、 作用:可以快速、方便的的对数据做一些处理和操作,方便程序的调用和执行。
- 创建工具类
1、 创建工具类: (1) 指定工具类的名称:ArrayTool (2) 功能: 数组的遍历 获取数组的最大值 获取数组的最小值 数组元素的交换 数组元素反转
- Arrays类型 * 概述 操作数据中数据的工具类 * 特点 提供了操作数组的各种静态方法,直接通过类名调用 工具类不能通过构造创建对象,因为构造方法私有化 当工具类在java.util,使用需要导包 * 方法介绍 + binarySearch(byte[] a,byte key) 查找某个元素在数组中的索引,按照二分查找法查找,数组需要升序排列 + equals(char[] a,char[] a2) 比较两个数组是否一样(比较两个数组的元素是否一样,顺序也需要相同) + sort(byte[] a) 将数组进行升序排列 + toString(int[] a) 遍历参数数组,通过字符串方式进行遍历,返回值是一个字符串 + fill(int[] a,int val) 将val参数填充到数组a中,原数组中的内容都被参数val替换 - Object类型 * 概念 Object是类层次结构的根类,每个类都使用Object作为超类,所有对象(包括数组)都实现这个类的方法,随意定义一个类型,不手动显示其父类,那么这个类的父类就是Object类 * 特点 这个类型在java.lang包中定义 * 构造方法 + 作用 本类可以创建对象 需要让子类访问父类的构造 + 格式 Object() + toString方法 - 概述 返回当前对象的字符串表示,返回的当前对象的地址 默认Object类的toString方法,由getClass().getName() + @Integer.toHexString(hashCode) 这几部分组成 getclass().getName()表示类的完全限定名 hashCode()表示根据内存地址用过哈希算法生成的哈希码值 对象返回这样一个地址值的字符串,没有什么意义,因此对于子类而言,需要重写父类的这个方法 重写的原则,返回该对象中的所有成员变量的值(对象的属性) 快捷生成:alt + shift + s s->或者 点击 toString方法 如果需要使用该方法,只需使用该对象名称即可,因为默认调用 + equals方法 - 概述 概述 public boolean equals(Object obj) 指示其他某个对象是否于此对象“相等” 对于任何非空引用值x和y,当且仅当x和y引用同一个对象时,此方法才返回true(x==y 具有值true).也就是在Object类型中,比较的是两个引用是否指向了同一个对象,如果是,才返回true,相当于是在比较两个对象地址值是否相同 3、实际生活中,比较两个对象的内存地址,没有什么意义.因此在自定义的子类中,都要重 写 这个方法. 4、重写原则:一般比较两个对象中的所有属性,是否全部相同. 5.快捷键生成:alt +shift + s h 或者 点 击 equals() and hashCode()方法. - == 和 equals的区别 * 相同点 都可以比较数据是否一样,如果一样返回true,不一样返回false * 不同点 + 比较内容不同 ==即可以比较基本数据类型,也可以比较引用数据类型 equals只能比较引用数据类型 + 比较规则不同 ==在比较基本数据类型时,比较的是数据值是否一样,在比较引用数据类型时比较的是地址值是否一样 equals方法在重写之前比较的是地址值是否一样,在重写之后,比价的是属性值是否一样 + 使用不同 如果需要比较元素的数据值可以使用==或者!= 如果需要比较对象的地址,可以使用==或者!= 如果需要比较对象的属性值,可以重写equals方法来比较 - Scanner类型 * 概述 概述:一个简单的文本扫描器,可以使用正则表达式解析原始类型和字符串 * 构造方法 + Scanner(File f) 扫描指定文件 + Scanner(String path) 扫描指定的路径 + Scanner(InputStream is) 扫描指定的输入流 * 常用功能 + 录入基本数据类型 注意事项:这些方法,既可以以换行当做结束的标志,也可以以空格当做一次结束的标志 - nextByte() - nextShort() - nextInt() - nextLong() - nextFloat() - nextDouble() - nextBoolean() + 录入字符串类型 注意事项:使用以空格作为结束方法之后,不能继续使用换行作为结束的方法,否则以换行结束的方法,会被默认跳过 解决方案: 可以多写一个nextLine() 新建一个Scanner对象,来使用nextLine - next() 可以录入下一个完整的标记,返回一个字符串,通过空格来分隔各个标记 - nextLine() 可以录入下一个完整的标记,返回一个字符好惨,通过换行符来分隔各个标记 - String类型 * 概述 概述 用来描述字符串的类型 引用数据类型 在java.lang包定义不需要导包。 * 特点 String类型所表示的每个字符串都可以理解为是他的一个对象 如果String类型直接接收一个字符串常量,name这个字符串常量在常量池中定义,引用中存储的是常量池中字符串的地址值而不是数据本身。 如果String类型通过new关键字创建,name会在堆内存中创建一个对象,当前地址指向对内存中的对象(对象中会维护一个字符数组). 字符串本身并不能被修改,String类型是一个不可变的字符序列 如果使用=接收一个常量,常量本身不能被修改 如果使用new关键字创建了一个字符串对象,当前对象中会维护一个字符数组,用来存储当前字符串,这个维护的字符数组是private修饰的,没有提供共欧诺个的该值方法,所以只能赋值和访问,不能修改 * 构造方法 + String() 空参构造 + String(byte[] byte) 讲一个字节数组转成一个字符串 解码 + String(byte[] byte,in offset,int length) 将字节数组的一部分转成字符串 + String(char[] value) 讲一个字符数组转为一个字符串 + String(char[] value,int offset,int count) 将字符数组的一部分转成字符串 + String(String original) 将字符串存储到字符数组中 * 判断功能 + contains(CharSequence s) 判断是否包含参数 + endsWith(String suffix) 判断调用者字符串是否以参数字符结尾 + startsWith(String prefix) 判断调用者字符串是否以参数字符串开头 + equals(Object anobject) 判断两个字符串是否一样 + equalsIgnoreCase(String anotherString) 忽略大小写判断两个字符串是否一样 + isEmpty 判断调用者是否为空 * 获取功能 + charAt(int index) 获取index索引对应的字符 + concat(String str) 拼接字符串 + indexOf(int ch) 获取ch字符串在字符串中的索引 + indexOf(int ch,int fromIndex) 从指定位置寻找str出现的索引 + indexOf(String str) 找str字符串在调用者中出现的索引 + indexOf(String str,int fromIndex) 从指定位置寻找str出现的索引 + lastIndexOf() 从后往前找指定元素出现的索引 + length() 返回字符串的长度 + substring(int beginIndex) 从参数索引开始往后截取字符串,形成一个新串 + substring(int beginIndex,int endIndex) 截取字符串的一部分,形成一个新串,包含头部索引,不包含尾部索引 * 转换功能 + getBytes() 将字符串转成字节数组 + toCharArray() 将字符串转为字符数组 + toLowerCase() 将字符串转为全小写形式 + toUpperCase() 将字符串转为全大写形式 + valueOf(参数) 将基本数据类型数据的参数或者引用数据类型转为字符串类型,当前方法是一个静态方法,可以通过类名直接调用 + trim() 去掉前后两边的空格 + replace(char oldChar,char newChar) 将old元素改为new元素
- 工具类优化
1、 工具类优化: (1)方法都是静态的,不需要创建对象; (2)创建对象会浪费系统资源,控制外界不能随意的创建对象。 方式:使用构造方法私有化
- 原因
1、 制作API原因: 工具类准备好之后,后续只需要使用编译好.class的字节码文件即可,但是编译好的字 节码文件开发者并不能看懂,所以需要进行对应帮助文档的制作。
- 文档注释
文档注释:用于给代码生成帮助文档的注释 格式: /** 文档注释 */ 特点: 不能嵌套
- 帮助文档注解
帮助文档注解:将来可以被文档生成工具解析出来的格式,可以解析出来其中的数据 作者:@author 名称 当前版本:@version v1.0 上一个版本:@since 参数:@param 返回值:@return
- 生成帮助文档
使用jdk中的bin目录中的javadoc这个工具,就可以生成帮助文档 Javadoc -d ArrayToolDoc -author -version 源代码文件
StringBuilder
- 概述
概述:用来表示字符串的类型
- 特点
是一个可变的的字符序列 在lang包不需要导包 此类中维护也是一个字符数组,用来存储字符串类型
-
String、StringBuilder区别
- 相同点
两个类型都可以表示字符串
- 不同点
String是不可变的字符序列,本类中没有提供修改成员变量的方法 StringBuilder是可变的字符序列,因为类中提供了修改成员变量的方法
- 拼接效率的区别
1、效果: (1)使用String类型拼接字符串效率低 (2)使用StringBuilder类型拼接字符串效率高 2、原因: (1)String类型是一个不可变的字符序列,不能在对象本身基础上进行拼接数据 系统会默认提供一个StringBuilder对象,拼接,拼接之后转为String对象 (2)StringBuilder类型是一个可变的字符序列,可以在对象本身基础上拼接数据
-
StringBuilder、StringBuffer区别
- 相同点
都可以表示可变的字符序列 两个类型中的方法都一样
-
不同点
- 版本不同
StringBuilder:jdk1.5出现 StringBuffer:jdk1.0出现
- 线程安全不同
StringBuilder线程不安全(单线程中用的多一点) StringBuffer线程安全(多线程中多一点)
- 效率不同
StringBuilder使用效率高 StringBuffer使用效率低
-
构造方法
- StringBuilder()
创建一个初始值为空的字符串对象,数组的初始大小为16
- StringBuilder(int c)
创建一个初始值为空的字符串对象,数组的初始大小为c
- StringBuilder(String str)
创建一个初始值为str的字符串对象,数组初始值大小为str.length+16
-
获取长度方法
概述:StringBuilder对象中维护的是一个字符数组,所以可以获取字符数组的长度和元素的个数
+ capacity()
返回对象的初始容量
+ length()
返回字符串对象
-
常用的方法
- 增加
注意事项:如果初始容量不够使用,会自动扩充空间,当前容量*2+2
- append(int i) 在字符串基础上追加数据,可以加任何类型的数据 - insert(int offset,char c) 在指定索引添加数据,索引的范围:0-length()
-
删除
- delete(int start,int end)
删除从start开始到end-1结束的字符
- deleteCharAt(int index)
删除指定索引位置上的字符
-
替换
- replace(int start,int end, String str)
将指定索引范围的字符换成新的字符
-
反转
- reverse()
将字符串在本身的基础上进行反转
基本类的包装类
- 概述
1、基本数据类型:四类八种。变量中存储的是数值本身而不是数据的地址。
- 特点
基本类型数据类型特点: (1)基本数据类型只能表示一个数据,类型中并没有一些特殊的方法来操作数据。 (2)需要对基本数据类型进行包装升级,包装之后,不仅可以表示数据,也有一 些方法来操作数据。
-
罗列
-
byte
- Byte
-
short
- Short
-
int
-
Integer
- 概述
(1)int类型只能表示一个整数 (2)Interger类型中不仅维护一个整数,还有一些操作该整数的方法
-
构造方法
- Integer(int value)
Integer(int value) :通过有参构造给类型中维护的整数赋值
- Integer(String s)
通过字符串给整数赋值,但是字符串只能是数字类型的字符串
-
维护的静态变量
- static BYTES
用于表示二进制补码二进制形式的 int值的字节数。
- static MAX_VALUE
一个持有最大值一个 int可以有2 31 -1。
- static int MIN_VALUE
的常量保持的最小值的 int可以具有,-2 31。
- static int SIZE
用于表示二进制补码二进制形式的 int值的位数。
- static TYPE
类原始类型 int的 类实例。
-
常用的方法
-
非静态方法
- xxxvalue()
将包装类的对象转为基本数据类型
-
静态方法
- parseInt(String s)
将字符串s通过十进制转为基本数据类型的整数
- parseInt(String s,int radix)
将字符串s当做radix进制转为一个基本数据类型整数
- toBinaryString(int i)
将i通过二进制转为字符串
- toHexString(int i)
将i通过十六进制转为字符串
- toOctalString(int i)
将i通过8进制转为字符串
- toString(int i,int radix)
将i通过指定进制进行转换,转成字符串
- valueOf(String s,int radix)
将字符串s通过指定进制转为一个包装类的对象
-
-
-
long
- Long
-
float
- Float
-
double
- Double
-
char
- Character
-
boolean
- Boolean
-
自动装箱、拆箱
- 装箱
装箱:将基本数据类型包装为引用数据类型的对象
+ 自动装箱
自动装箱:直接使用用引用数据类型的变量,接收基本数据类型的元素
- 拆箱
拆箱:将引用数据类型的对象转为基本数据类型
+ 自动拆箱
直接使用基本数据类型的变量,接收引用数据类型的变量,然后使用引用数据类型的对象进行数据的运算
正则表达式
- 概念
正则表达式其实就是使用一个字符串表示一类规则
- 作用
普通的字符串只能表示和本身所表示的数据,但是正则表达式不仅可以表示字符串本身 数据,还可以表示一类字符串,可以做为一类字符串的依据
- 好处
1、可以使用简单的代码完成发杂的逻辑
- 字符类
使用单引号引起来的单个字符 char
+ 定义
1、字符类: (1)使用 [] 表示某一个单个符号 [abcdefg] (2)不管 [] 中定义多少个字符,都只能表示其中一个字符
+ 使用方式
1、使用方式:要判断一个字符串是否满足某个正则表达式,需要使用matches方法
+ 注意事项
1、注意事项: (1)方法的参数中定义的是一个字符串规则 (2)不管中括号中定义了多少个字符,只能表示其中一个
+ 案例
[abc]:a,b,c其中一个 abc:除了abc之外的其中一个 [a-f]:a-f之间的其中一个
- 预定义字符
1、预定义字符:如果某些字符经常使用,就将这些字符定义为预定义字符
+ 特点
1、特点:预定义字符只能表示单个字符
+ 罗列
- .
表示所有的单个字符
- \d
所有的数字字符
- \D
所有的非数字字符
- \s
所有的空格字符
- \S
所有的非空格字符
- \w
表示0-9a-zA-Z\_
- \W
除了\w的其中一个字符
-
数量词
- 概述
1、字符类和预定义字符类都只能表示单个符号,如果需要表示多个符号,需要通过数量词 来修饰。
- 特点
1、数量词只能修饰前面的那一个字符
-
分类
-
模糊数量词
- x?
x这个字符可以出现0次或者1次
- x+
x这个字符出现1次或者多次
- x*
x这个字符可以出现0次1次或者多次
-
精确数量词
- x{n}
表示x这个字符正好出现n次
- x{n,}
表示x这个字符至少出现n次
- x{n,m}
表示x这个字符出现n-m次
-
-
方法
- matches(String s)
判断调用者字符串是否和s匹配
- split(String s)
1、切割调用者字符串,只要调用者字符串中满足s这个规则都可以进行切割 返回值是一个字符串数组,将切割后的内容存入到字符串数组中
- replaceAll(String s1,String s2)
1、将满足s1的字符串全部替换成s字符串
常用类型
-
Math
- 概述
Math类型是一个包含执行基本数字运算的方法
- 特点
(1)该类是一个工具类,类中全是静态方法 (2)该类在java.lang包,使用时不需要导包
- 静态字段
静态字段:常量
- E 自然对数的底数 - PI 圆周率
-
常用方法
- abs(参数)
返回参数的绝对值
- ceil(double a)
向上取整
- floor()double a
向下取整
- max(float a,float b)
求两个数的最大值
- min(a,b)
求两个数组的最小值
- pow(double a,double b)
求出参数a的b次方
- round(float a)
求出a的四舍五入的结果
- random()
获取一个随机数 0.0-1.0之间
-
System
- 概述
1、概述:System是和系统资源交互使用的一个类型 类型中定义了几个有用的字段和方法
-
常用字段
- in
标准输入流,一般和Scanner类结合使用,默认关联到键盘
- out
标准输出流,一般和println方法结合使用,默认关联到控制台
- err
标准错误输出流,默认关联到控制台 以红色字体打印,一般是系统默认调用
-
方法
- gc()
强制运行垃圾回收器。强制垃圾回收器回收垃圾
- currentTimeMillis()
返回从1970年0时0分0秒到当前时间的毫秒值 计算机元年
-
BigInteger
- 概述
1、用来表示大范围的整数对象所属的类型
- 特点
(1)表示的整数可以超过long表示的范围 (2)java.math包,需要导包 (3)提供了操作整数的各种简单方法
-
构造犯法
- BigInteger(String val)
概述:将BigInteger的十进制字符串表示形式转换为BigInteger。
- BigInteger(String val,int radix)
概述:将指定基数中的BigInteger的String表示形式转换为BigInteger。
-
常用方法
- abs()
1、public BigInteger abs() :返回BigInteger对象的绝对值
- negate()
2、public BigInteger negate() :取该对象的反数
- add(BigInteger val)
3、public BigInteger add(BigInteger val): 加法运算
- subtract(BigInteger val)
4、public BigInteger subtract(BigInteger val) :减法运算
- multiply(BigInteger val)
5、public BigInteger multiply(BigInteger val) :乘法运算
- divide(BigInteger val)
6、public BigInteger divide(BigInteger val):除法运算
-
BigDecimal
- 概述
概述:可以准确操作浮点数类型数据所属的类型
- 特点
2、特点: (1)在Java.math包,使用需要导包 (2)可以精确表示小数的位数 (3)提供了操作小数的各种常用方法
-
构造方法
- BigDecimal(double val)
public BigDecimal(double val):将double类型的数据转换成BigDecimal对象
- BigDecimal(String val)
、public BigDecimal(String val):将String类型的数据转换成BigDecimal对象
- valueOf(long l)
BigDecimal valueOf(long l):将long类型的数据转为BigDecimal对象
- valueOf(double d)
BigDecimal valueOf(double d):将double类型的数据转为BigDecimal对象
-
常用方法
- add(BigDecimal augend)
加法运算
- subtract(BigDecimal subtrahend)
减法运算
- multiply(BigDecimal multiplicand)
乘法运算
- divide(BigDecimal disisor)
除法运算,如果除不尽运行错误
- divide(BigDecimal divisor,int scale,int roundingMode)
精确除法运算
-
注意事项
- 参数作用
除数 精确位数 舍入方式
-
常用舍入模式
- BigDecimal.ROUND_UP
向上取整
- BigDecimal.ROUND_FLOOR
向下取整
- BigDecimal.ROUND_HALF_UP
四舍五入
-
Date
- 概述
Date是表示时间的类型,此类可以表示特定的瞬间,精确到毫秒.是java中提供的 表示时间日期数据的对象
- 特点
(1)此类在java.util包,需要导包 (2)此类大部分方法已经过时,由Calendar类型代替
-
构造方法
- Date()
分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)
- Date(long date)
分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为" 历元(epoch)",即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定 毫秒数。
-
常用方法
- getTime()
返回自1970 年1月1日 00:00:00 GMT 以来此 Date 对象表示的 毫秒数
- setTime(long time)
设置此Date对象,以表示 1970 年1月1日 00:00:00 GMT 以后 time 毫秒的时间点
-
SimpleDateFormat
- 概述
概述:是一个与语言环境有关的方式来格式化和解析日期的具体类
- 特点
特点: (1)java.text包,需要导包使用 (2)可以按照自定义的方式格式化日期 (3)可以按照指定格式解析日期
-
构造方法
- SimpleDateFormat()
将一个 Date 格式化为日期/时间字符串
- SimpleDateFormat(String pattern)
指定解析日期的格式创建对象
-
常用方法
- String format(Date date)
将一个 Date 格式化为日期/时间字符串
- Date parse(String source)
从给定字符串解析文本,以生成一个日期 注意事项:如果指定的格式不匹配,抛出ParseException
-
Calendar
- 概述
、概述:用来表示和操作日历时间各个字段的类型
- 特点
(1)java.util包,需要导包 (2)类型对象中中提供了各个时间字段,如:年、月、日、星期等 (3)类中提供了各种方法可以操作各个时间字段 (4)此类是一个抽象类,不能直接创建对象
-
常用字段
- DAY_OF_MONTH
本月第几天
- DAY_OF_WEEK
星期几(星期日-星期六)
- DAY_OF_YEAR
当前年的第几天
- HOUR_OF_DAY
当天小时数
- HOURS
当前小时(12小时制)
- MINUTE
当前分钟
- SECOND
当前秒
- WEEK_OF_MONTH
本月第几周
- WEEK_OF_YEAR
本年第几周
- YEAR
当前年份
- MOTH
但前月份(系统默认月份是从0开始)
-
常用方法
- Calendar getInstance()
public static Calendar getInstance():使用默认时区和语言环境获得一个Calendar类对象
- set(int field,int value)
public void set(int field,int value):将给定的日历字段设置为给定 如果传入两个参数,第一个参数默认为某个时间字段,第二个参数默认为要改的值 如果传入三个参数,默认为年月日 如果传入五个参数,默认为年月日,时分 如果传入六个参数,默认为年月日,时分秒
- get(int field)
public int get(int field):返回给定日历字段的值
- add(int field,int amount)
public abstract void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减 去指定的时间量 可以传入正值,表示增加 可以传入负值,表示减少
- getTime()
1、public final Date getTime():返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移 量)的 Date 对象
-
NumberFormat
- 概述
NumberFormat是所有数值格式的抽象基类,此类提供格式化和解析数值的方式,可 用于格式化和解析任何语言环境的数值
- 特点
特点: (1)java.text包,需要导包 (2)该类是一个抽象类,不能创建对象 (3)该类提供了表示数字的不同格式
-
常用方法
- NumberFormat getInstance()
- NumberFormat getCurrencyInstance()
- NumberFormat getPercentInstance()
- setMaximumFractionDgits(int newValue)
- setMaximumIntegerDgits(int newValue)
- format(double number)
异常
- 概述
1、概述: 客观角度:不符合现实生活的各种情况,都可以理解为是异常 Java语言角度:在代码的运行过程中,出现的各种错误导致程序停止运行,那么这些错 误就是异常。 注意:异常在程序中都是通过对象来表示的。在程序中,如果出现错误,系统会默认将 出现错误的原因,位置,类型等信息封装到一个异常对象中。
-
体系
-
顶层父类
- Throwable
Throwable:抛出。异常体系的顶层父类。
* Error Error:错误。如果出现了一些问题,这些问题非常严重,不能通过代码解决。 * Exception Exception:异常。如果出现一些问题,这些问题可以通过代码解决,那么就表示这些问 题不是很严重,这些问题就属于异常。 + 编译时异常 1、编译时异常:在代码编译阶段,系统会检查代码的语法格式等情况,如果在检查的过程 中出现了问题,这些问题就属于编译时异常。如果出现编译时异常,需要通过代码去捕 获或者声明。 - !RuntimeException类歪的所有异常类型 + 运行时异常 1、运行时异常:在代码编译阶段不对代码进行检查,但是在代码运行阶段,如果出现了一 些逻辑等会导致程序意外终止的问题,这些问题就属于运行时异常,如果出现了运行时 异常,需要去捕获处理。 - RuntimeException类及其子类
-
-
处理异常的方式
- JAVA虚拟机默认处理异常
1、如果在代码中的某个方法内出现了错误情况,系统会将这个错误发生的原因,发生异常 类型,发生的路径封装到异常对象中。 2、如果当前方法中没有处理这个异常对象,就将异常往上抛出,抛给调用该方法的方法。 3、如果调用的方法也没有处理异常,那么就一层一层往上抛出,直到抛给main方法,main 方法再抛给虚拟机 4、虚拟机将当前异常对象通过标准错误流,打印到控制台,并结束自己。
-
手动处理异常的
- 异常的声明
异常的声明:如果在某个方法中出现了编译时异常,可以在当前方法上声明这个异常的 类型,声明之后编译时异常就会消失。
* 注意 注意: (1)异常的声明只能处理编译时异常。 (2)异常的声明不能从根本上解决问题。 声明一个编译时异常类型之后, 系统不会在编译期间检查这段代码, 但是在运行阶段,如果传入的数据不正确,也有可能出现错误情况。
- 异常的捕获
异常的捕获:如果代码的某个位置会出现了错误情况,可以使用特定的格式,捕获这个错误,捕获之后可以按照自己定义的方式去处理异常。
* 注意 (1)既能处理编译时异常,也能处理运行时异常。 (2)可以从根本上解决问题。 * 格式 + try...catch - 格式 * 单catch + 格式 try{ 可能会出现错误的代码 }catch(异常类型 异常对象名称){ 处理异常的方式 } + 注意事项 (1)如果在某行代码中,出现了异常,立即去catch块中去匹配异常类型,出现错误 的代码后面的代码就不能执行了。 + 执行流程 1、执行流程: 1、先执行try中的代码,检测是否出现异常 2、如果try中的代码没有出现问题,trycatch直接结束,代码正常执行trycatch后面的 代码。 3、如果try中出现了异常,程序立即跳转到catch中查看出现异常所属的类型和catch 中声明的类型是否一样,如果一样,就捕获该异常按照指定的方式去处理异常,处 理之后,trycatch结束,程序继续运行。 4、如果try中出现了catch中没有声明的异常类型,就不能捕获该异常,这时虚拟 机来处理这个异常(默认处理方式)。 * 多catch + 格式 1、格式: try{ 可能出现错误的代码 }catch(异常类型1 对象名1){ 异常1的处理方式 }catch(异常类型2 对象名2){ 异常2的处理方式 }... + 流程 1、先执行try中的代码,检测是否出现异常 2、如果出现了异常, 就先和异常类型1匹配,如果能匹配上就执行异常1的处理方 式,处理之后,直接结束整个try…catch语句,执行之外的代码。 3、如果不能和异常类型1匹配,就继续和异常类型2匹配,如果能匹配上,就执行异 常类型2的处理方式,之后结束整个try…catch语句,执行之外的代码。 4、如果异常类型2不能匹配,依次类推,往后匹配。 5、如果出现的异常,catch中的类型都不能匹配,虚拟机默认处理 + 注意事项 1、注意事项: 1、如果定义了多个catch语句去匹配多个异常类型,异常类型中存在子父类的关系, 父级的异常类型不能定义在子级异常类型前面。 原因: 如果父类异常定义在前面,后面定义的子类或者间接子类异常没有执行的机会 可以将父类异常类型定义在后面,如果前面的类型无法匹配,可以使用父类异常 匹配 2、如果多个异常类型想要执行一种处理方式,可以使用 | 符号去定义类型(jdk1.7) 可以使用多个 | 来定义多个异常类型,只要出现其中一种,都可以去捕获处理 + try...catch...finally - 格式 try{ 可能会发生错误的代码 }catch(异常类型1 异常对象1){ 异常1的处理方式 }catch(异常类型2 异常对象2){ 异常2的处理方式 … }finally{ 一定需要执行的代码 } - finally * 意思 1、finally: 终于,最终 * 使用原因 使用原因: (1)如果有某些代码一定要执行,将代码放在try中或者catch中或者trycatch外 都有可能执行不到 (2)将这段代码放在finally块中,不管遇到什么情况,系统都会去执行finally中的 内容。 + try...finally - 格式 1、格式: try{ 第一段代码 }finally{ 第二段代码 } - 作用 1、作用: 如果在程序中,有多段代码,多段代码都需要有执行的机会,那么可以将这多段代码, 分别放在try中和finally中,这样,多段代码之间就会互不影响,都有执行的机会。 用来分隔代码,让代码之间互不影响,都有执行的机会。
-
方法
- 概述
1、概述:在异常的体系中,有很多类型,但是大部分类型都没有属于自己的功能,功能 一般都已经在顶层的父类中定义了,所以可以使用父类中定义的方法。
-
常用方法
- getMessage()
返回异常的原因
- getCause()
返回引起调用者发生异常的原因
- toString()
返回该异常对象发生的原因及所属性的类型
- printStackTrace()
返回该异常发生的路径,原因,及类型
-
构造方法
- Throwable()
创建一个没有任何属性值的异常对象
- Throwable(String message)
创建一个有原因的异常对象
- Throwable(Throwable cause)
创建一个是由其他异常引起的异常对象
-
throw、throws
-
throw关键字
- 概述
抛出异常
- 使用场景
1、使用场景:如果在某个方法中出现了和正常生活不符合的情况,开发人员可以在该方法 中创建一个异常对象,但是创建的异常对象自己不会自动抛出,需要使用throw关键字 抛出异常。
- 注意
1、注意: (1)如果抛出的是一个运行时异常,那么该异常在编译阶段不做检查,在运行阶段一 旦执行该异常,就会出现对应的错误。如果出现错误,可以去捕获和处理。 (2)如果抛出的是一个编译时异常,不需要等到运行阶段,在编译阶段这个异常就会 发生。出现编译时异常,可以捕获处理,或者进行声明。
-
throws关键字
- 概述
声明一个异常类型
- 使用场景
在某个方法中,如果出现了编译时异常,并且没有进行捕获处理,那么可以对该编译时 异常进行声明,声明之后,在代码编译阶段就不会在检查这段代码。
- 格式
修饰符 返回值类型 方法名称 (参数列表) throws 异常类型1,异常类型2…{ 方法体语句; }
- 注意事项
注意事项: (1)异常的声明,不能从本质上解决问题,只能在编译阶段不检查这段代码 如果后续传入一些错误的数据,在运行阶段也可能会发生错误。 (1)如果方法1中进行了异常的声明,方法2调用了方法1,那么方法2需要对该异 常进行捕获或者处理。 (2)在声明异常的时候,尽量声明小的异常类型
-
区别
- 作用不同
throw:用来抛出一个异常对象 throws:用来声明异常类型
- 使用位置不同
throw:在方法中使用 throws:在方法的声明上(参数列表后)使用
- 使用方法不同
throw:一次只能抛出一个异常 throws:同时可以声明多个异常类型,之间使用逗号分隔
-
-
自定义异常
- 使用原因
在异常的体系中官方定义了很多异常类型,但是大多类型都没有自己特殊的方法和属 性,目的就是为了使用不同的类型来区分各种问题,当看到对应的类型时,就知道代码 中出现了什么问题,方便去开发者分析代码并解决问题。
- 步骤
1、步骤: (1)创建一个类型以Exception结尾 (2)将这个异常类型继承Exception或者RunTimeException (3)在该类中调用父类的构造方法,用于让子类创建对象
可变参数
- 概述
可变参数又称参数个数可变,用作方法的形参出现,name方法参数个数就是可变的了,方法的参数类型已经确定,个数不确定,我们可以使用可变参数
- 好处
由于参数数目不稳定,使用可变参数函数能缩短编码,灵活性和易用性较高
- 格式
修饰符 返回值类型 方法名(数据类型…变量名){ 方法体 }
- 注意事项
可变参数底层是使用数组实现的 如果方法中存在多个参数,只能存在一个可变参数 一个方法的参数列表中,只能存在一个可变参数 在传递实际参数时,数据类型要和可变参数的数据类型对应
集合
- 概念
用来存储多个数据的容器
-
集合和数组的区别
- 共同点
都是用来存储数据的容器,都可以存储多个数据
- 不同点
数组的大小是固定的,不能新增也不能减少元素;集合的大小是可以进行改变的,可以往集合中新增元素或者删除元素 数组即可以存储基本数据类型,也可以存储引用数据类型的数据,集合只能存储引用数据类型的数据
-
使用集合的原因
数据的大小不能伸缩,如果需要增加或者删除元素,操作起来比较麻烦;集合可以直接增加或者删除元素,操作起来比较容易 数据中操作元素的功能比较少,集合可以有很多方法操作元素
-
体系
-
单列集合体系
-
Collection接口
- list接口
1、概述:List集合也是一个接口,根据底层存储数据方式的不同有不同的实现类
+ ArrayList实现类 - 概述 1、List集合的实现类,本类没有特殊的方法,只能使用接口中定义的方法 - 特点 1、特点: (1)底层数组实现,可以表示元素有序 底层是通过数组来实现的,通过数组空间的连续来表示元素的有序 (2)查询元素的效率高,增删元素的效率低 - 总结 总结: (1)创建一个集合对象,其实就是创建了一个数组 (2)如果需要增加元素: 先判断维护的数组空间是否够用,如果不够用,将空间扩充为原来的1.5倍 扩充之后,将老数组中的元素,赋值到新数组中,在指定位置或者在后面添加 新元素 (3)如果需要删除元素: (1)如果删除某个索引对应的元素,先判断索引是否越界,越界则抛出索引越界 异常,不越界,就删除移除索引对应的元素,将后面的元素往前移动 (2)如果要删除某一个元素,通过遍历数组,查询相同的值,相同就删除,删除 之后,后面的元素往前移动。 + LinkedList实现类 - 概述 1、属于List接口的实现类,可以使用接口中继承方法 - 特点 1、特点: (1)底层通过双向链表实现,可以保证元素有序 (2)查询元素效率低,增删元素效率高 - 方法 1、特有方法:因为linkedList可以记录头部和尾部元素的地址,所以有一些操作头部和尾部 元素的方法: * addFirst() 在头部位置添加元素 * addLast() 在尾部添加元素 * removeFirst() 删除头部位置的元素 * removeLast() 删除尾部位置的元素 * getFirst() 获取头部元素 * getLast() 获取尾部元素 * pop() 移除集合第一个元素并回去该元素 * push(E e) 将指定元素添加到集合的第一个元素中
- set接口
1、概述:该集合继承自Collection接口,它与Collection接口中的方法基本一致,并没有对 Collection接口进行功能上的扩充,只是比Collection接口更加严格了。
+ HashSet实现类 + TreeSet实现类
-
Colletion集合
- 意思
收集,集合
- 概述
此类是单列集合的顶层接口,任何单列结合都属于该接口的子接口或者实现类
- 特点
是一个接口不能创建对象,只能通过实现类创建对象访问其中的方法 在java。util包,需要导包使用 Collection中定义的方法,子接口和实现类都可以去使用
-
常用方法
- add(E e)
往集合中添加元素
- addAll©
将集合c中的元素全部添加到调用者集合中去
- remove(object o)
删除集合总中的o元素
- removeAll©
删除调用者集合中和c集合中相同的元素
- clear()
清空集合
- contains(Object o)
判断调用者集合中是否包含o元素
- containsAll©
判断调用者集合中是否全部包含jihec的所有元素
- isEmpty()
判断集合是否为空
- size()
返回集合中元素的个数
-
遍历方式
- 转数组遍历
方式:转数组遍历,将集合通过某个方法转为一个数组,再遍历数组,间接地遍历集合
集合转为数组的方法:toArray()
- 迭代器遍历
方式:使用迭代器遍历集合
- 迭代器方法 获取迭代器的方式,通过集合定义的方法来获取:iterator() * next() * hasNext() * remove() - 注意事项 1、使用next方法可以获取集合中的所有元素,虽然反复使用的方法是一样的,但是返 回的数据不同。 2、next方法不仅可以获取元素,还可以移动指针,获取一次之后,指针指向下一个元 素。 3、如果没有下一个元素,仍然获取出现java.util.NoSuchElementException(没有当前元 素异常)。 4、可以使用hasnext方法来判断集合中指针指向的当前元素是否存在 5、反复使用next和hasnext方法比较麻烦,所以使用while循环来简化操作。
- 增强for循环
2、增强for循环: (1)它是JDK5之后出现的,其内部原理是一个Iterator迭代器 (2)实现Iterable接口的类才可以使用迭代器和增强for循环完成数组和Collection集合的遍历
- 格式 for(元素的数据类型 元素名称:集合或者数组名称){ 元素名称的使用 } * 说明 元素的数据类型:集合或者数组中元素的类型 元素名称:给集合或者数组中的每一个元素起的一个合法的表示符 集合或者数组名称:要遍历的数组或者集合名称
-
List集合
- 概述
list结合是Collection接口下的子接口
- 特点
1、特点: (1)属于一个单列集合 (2)List也是一个接口,不能直接创建对象 (3)该集合中的元素特点: 有序:元素存入的和取出的顺序可以保证一致 有索引:每个元素都有自己的一个位置,通过有序的序号来表示这个位置,索引 范围:0—集合长度-1 可重复:集合中可以存储相同的元素值
-
方法
- add(int index,E element)
往集合中的指定位置添加元素
- get(int index)
获取集合中指定元素的值
- remove(int index)
删除指定位置的元素
- set(int index, E element)
修改集合中指定位置的元素值为ele
-
Set集合
- 概述
概述:该集合继承自Collection接口,它与Collection接口中的方法基本一致,并没有对 Collection接口进行功能上的扩充,只是比Collection接口更加严格了
- 特点
特点: (1)在java.util包中,使用需要导包 (2)该类有两个实现类:HashSet 和 TreeSet (3)该类元素特点: 不可重复:集合中不能存储相同的元素值 没有索引:集合中的元素没有一个特定的符号来表示 无序:元素存储的顺序和取出的顺序不能保证一致
-
遍历
- 使用迭代器遍历
使用迭代器遍历 (1)获取迭代器对象 (2)hashNest方法判断集合中是否有下一个元素 (3)next方法获取下一个元素
- 使用增强for遍历
使用增强for遍历 格式:for(元素数据类型 元素名称:集合名称){ 该元素的使用方式 }
- 转数组遍历
转数组遍历: 使用不带泛型转数组:toArray(); 转数组之后,返回的数组是Object类型,使用数据的特殊方法时,需要向下转型 使用带着泛型转数组:toArray(T []): 转数组之后,返回的数组类型就是传递的数组类型,不需要向下转型
- 注意 如果传入的数组空间正好够用,将集合中的元素存储到传递的数组中 如果传入的数组空间不够用,系统会新建一个相同数据类型的数组,来存储集合中的元素,那么返回的数组和传递的数组,不是同一个数组 如果传入的数组空间太多,系统不会新建数组,直接将集合中的元素存储到传入的数组中,多余的空间使用默认值代替
-
实现类
-
TreeSet
- 概述
1、概述:当前集合为Set集合的实现类。
- 特点
集合中元素,存取无序(存入和取出的顺序),排列方式有序,没有索引,不可以重复 该集合没有特殊方法来操作元素,可以使用单列接口中继承的方法 可以按照一定的方式对集合中的元素进行排序存储 只有集合中的元素所属类型实现Comparable接口,并重写其中的方法,才可以使用TreeSet集合排序
-
构造方法
- TreeSer()
创建一个集合对象,对元素自然排序
- TreeSet(Comparator<? super E>comparator)
使用comparator比较器排序
-
comparable比较方法
(1)如果是一个基本数据类型对应的包装类型的元素,根据大小默认比较 (2)如果是非中文字符串类型,则按照字母的顺序排序 (3)如果是中文字符串则按照中文字符解码后的数字大小排序 (4)如果是自定义的类型对象,则按照该类型对Comparable接口方法重写的方式比较
* 比较原理 比较原理: (1)Comparable接口: 是一个比较接口 (2)需要重写该接口的方法: public int compareTo(Object o) (3)重写原则: 返回值为0 -- 相等 如果相等,就去重 返回值为正 -- this 大于 参数 this排后面 返回值为负 -- this 小于 参数 this排前面 注意: 方法返回的值,如果是正数,就判定调用者数据是大的,就自然排后面 方法返回的值,是负数,就判定调用者是小的,就排前面去 方法返回的值,为0,就表示两个数据是一样的,就去重 ``` 如果想要升序排列,就将调用者对象放前面,将参数对象放后面 如果想要降序排列,就将调用者对象放后面,将参数对象放前面 ``` * 自定义类重写原则 自定义类重写原则: (1)自定义的类实现Comparable接口 (2)重写接口中的compareTo方法 + 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
-
Comparator比较器
- 概述
概述:Comparator和Comparable一样都是用来比较数据的接口 2、Comparable接口如果使用,需要被自定义类实现,且重写其中的compareTo方法 3、Comparator接口如果使用,需要在创建TreeSet集合对象时传入一个该接口的实现 类对象,且重写其中的compare方法
- 方法
compare(Object o1,Object o2): 参数1表示要存储的数据,第二个参数表示集合中已经有的数据
如果想要升序排列,将参数放前面,集合中有的放后面
如果想要降序排列,将参数放后面,集合中有的放前面
- 子主题 1
- 子主题 1
-
HashSet集合
- 概念
属于set集合的实现类
- 特点
无序没有索引,不可以重复 该集合没有特殊的方法,可以使用单列接口中定义的方法 该集合存储元素的方式,底层是根据哈希表来进行存储的
- 哈希值
哈希值简介: (1)是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值 (2)如何获取哈希值 Object类中的public int hashCode():返回对象的哈希码值 (3)哈希值的特点 -同一个对象多次调用hashCode()方法返回的哈希值是相同的 -默认情况下,不同对象的哈希值是不同的,因为默认根据对象的地址值来获取 而重写hashCode()方法,可以实现让不同对象的哈希值相同
-默认情况下,出现的哈希值不同,肯定不是同一个对象 -如果哈希值一样,可能不是同一个对象
-
底层原理
- 元素去重原理
元素去重原理: 没有重写equals方法也没有重写hashcode方法,发现存储到集合中的元素即使属性值 一样,也没有去重 重写equals之后,发现并没有调用equals方法来去重 再次重写hashcode之后,发现元素根据属性去重了 结论: 存入元素时,先比较要存入元素的哈希值和集合中元素的哈希值,是否是一样的 如果要存入的元素哈希值和集合中元素的哈希值不同,直接存入集合 如果要存入元素的哈希值和集合中元素的哈希值相同,再次调用equals比较属 性值 如果比较属性值相同,就不存入集合 如果比较属性值不相同,存入集合
- HashSet jdk1.7原理
创建一个默认长度16,默认加载长度0.75的数组,数组名table 根据元素的哈希值跟数组的长度计算应存入的位置 判断当前位置是否为null,如果是null直接存入 如果不为null,表示有元素,则调用equals方法比较属性值 如果一样,则不存,如果不一样,则存入数组,老元素挂在新元素下面
- HashSet jdk1.8原理
创建一个默认长度16,默认加载长度0.75的数组,数组名为table 根据元素的哈希值跟数组的长度计算1应存入的位置 判断当前位置是否为null,如果是null直接存入 如果不为null,表示有元素,则调用equals方法比较属性值 如果一样,则不存,如果不一样,则存入数组,老元素挂在新元素下面
-
子类
-
LinkedHashSet
- 概述
是一个单列集合,HashSet集合的子类
- 特点
没有特殊的方法,可以使用父类中继承的方法 元素特点 无索引 不可重复:和父类去重原理一样 有序:可以保证元素存入和取出的顺序 原因:每一个元素都会记录下一个存入元素的地址,在取出元素的时候,根据寻找地址的方式来寻找下一个元素
-
-
-
单链集合特点总结
-
顶层接口Collection
-
list
- 特点
有序,有索引,可重复
-
实现类
- ArrayList
数组实现 增删元素慢 查询元素快
- LinkedList
链表实现 增删元素快 查询元素慢
-
set
- 特点
无序,无索引,去重
-
实现类
- TreeSet
实现comparable接口,重写compareTo方法来实现去重和排列顺序方式
- HashSet
通过重写equals和hashcode方法来实现去重排列
+ LinkedHashSet 有序 去重 无索引
-
-
-
并发修改异常
- 概述
1、ConcurrentModificationException 并发 修改 异常
- 原因
使用迭代器对象遍历集合的同时,使用了集合对象增加或者删除元素
- 解决
使用结合对象遍历,使用集合对象增加元素 使用迭代器对象遍历,使用迭代器对象增加元素
+ 集合 1、使用集合对象遍历,使用集合增加 使用list集合特有的方式遍历 使用集合中的add或者remove方法增加或者删除 + 迭代器 1、使用迭代器遍历,使用迭代器增加 (1)iterator()方法获取迭代器对象中只能使用删除方法,不能使用增加方法 (2)如果需要使用迭代器对象增加元素,可以使用List集合特有的方式来获取迭代器 对象: 获取方式:listIterator() add(E e) 添加元素 remove() 移除元素
-
-
双链集合
-
Map接口
- HashMap实现类
- TreeMap实现类
-
-
Map集合
- 概念
1、概念: 现实生活中,我们常会看到这样的一种关系:IP地址与主机名,身份证号与个人, 用户名与密码,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放 这种对象关系的数据,这个集合就是即Map接口。
- 特点
该接口是双列集合的顶层接口,不能直接创建对象 该类在java.util包中,使用时需要导包 该集合中的每个元素是由一对数组组成,即:键值对 键值是由 键(key)和值(value)组成 键值对中的键是唯一的(不可重复),无序的,值是可以不唯一的,一般是通过键来操作值
-
常用方法
- put(K jey, V value)
往集合中添加数据 如果添加的key是第一次出现,表示添加数据 如果添加的key值集合中已经存在,表示替换key对应的value
- remove(Obeject key)
根据指定的key删除对应的键值对
- remove(Obeject key,Object value)
根据键和值删除对应的键值对
- clear()
清空集合
- containsKey(Object Key)
判断集合中是否包含key
- containsValue(Object value)
判断集合中是否包含value
- get(Object key)
根据key值获取对应的value值
- isEmpty()
判断集合是否为空
- replace(K key,V value)
替换key对应的value值
- size()
获取集合中键值对的对数
-
遍历方式
- 通过key获取value值
先获取集合中的key到一个set集合中,遍历set集合获取每一个key,再通过key单独拿到对应的value即可 获取集合中的key到set集合中:keySet() 遍历set集合 通过get方法获取key值对应的value值
- 通过键值对对象获取键和值
1、先获取map集合中的键值对,获取的时候将键值对封装为一个个对象放到set集合中, 再遍历set集合获取每一对键值对对象,单独获取这一对数据的key和value. 2、获取键值对到set集合中:entrySet() 再获取每一对数据的时候,默认将每一对数据封装为一个个entry对象,一个对象中又包 含两个数据,分别为key和value. Entry是属于map集合的内部接口 3、遍历set集合,获取每一个entry对象 三种遍历方式 4、单独获取键值对对象中的key和value值:
-
实现类
-
TreeMap
- 概述
1、概述:是一个双列集合,是Map集合的实现类
- 特点
特点: (1)集合中的key值是唯一的,元素是无序的 原因: Key值去重和无序的方式,和TreeSet集合原理相同 (2)TreeSet集合和TreeMap集合的关系: TreeSet集合底层是由TreeMap实现的
-
HashMap
- 概述
1、概述:是一个双列集合,属于map集合的实现类。
- 特点
1、特点: (1)集合中的key值不可以重复,元素是无序的 原因: Key值去重和无序的方式,和HashSet集合的原理相同 (2)HashSet集合和HashMap集合的关系: HashSet集合底层是由HashMap集合实现的
- 验证 创建了一个HashSet集合,底层创建了一个HashMap集合 操作HashSet集合中的元素,其实就是在操作HashMap集合总的key值
-
子类
-
LinkedHashMap
- 概述
1、概述:是一个双列集合,是HashMap集合的子类
- 特点
本类中没有特殊方法,只能使用父类中继承的 集合中元素有序(存入和取出) 可以根据key值保证元素的有序,可以记录下一个key的地址 3.集合中的key值唯一
-
-
HashMap和HashTable
- 关系
1、HashMap和Hashtable都是用于存储键和值的对应关系,都是Map的实现类,都是使用 哈希表的方式存储。
- 不同点
1、不同点: 1、版本不同,Hashtable是jdk1.0版本出现的,HashMap是jdk1.2版本出现的 2、线程安全性不同,Hashtable是线程安全的,HashMap是线程不安全的 如果后续在多线程情况下需要使用线程安全的集合, 可以使用工具类中的方法来 获取 3、HashMap集合操作元素的效率高,HashTable集合操作元素的效率低 4、Hashtable不能存储null键null值,HashMap可以存储null键null值
* 版本不同 1、版本不同,Hashtable是jdk1.0版本出现的,HashMap是jdk1.2版本出现的 * 线程安全不同 线程安全性不同,Hashtable是线程安全的,HashMap是线程不安全的 如果后续在多线程情况下需要使用线程安全的集合, 可以使用工具类中的方法来 获取 * 操作效率不同 、HashMap集合操作元素的效率高,HashTable集合操作元素的效率低 * 存储null键null值不同 Hashtable不能存储null键null值,HashMap可以存储null键null值
-
-
线程安全、不安全总结
- StringBuilder/StringBuffer
StringBuilder线程安全,效率高,单线程使用 StringBuffer线程安全,效率低,多线程使用
- HashTable/HashMap
HashTable线程安全,效率低(不使用) HashMap线程不安全,效率高
synchronizedMap(Map<K,V>m):可以将线程不安全的集合转为线程安全的集合
- Vector/Arraylist
Vector:线程安全,效率低(不使用) Arraylist:线程不安全,效率高
synchronizedList(Listlist):可以将线程不安全的单列集合转为安全的集合
-
数据结构
-
栈
- 概述
栈概述:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作
- 特点
先进后出,(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。
-
相关概念
- 压栈
压栈就是存元素,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置
- 弹栈
弹栈就是取元素,把栈的顶端元素取出,栈中已有的元素依次向栈顶方向移动一个位置
-
队列
- 概述
队列概述:queue简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除
- 特点
先进先出(即,先存入元素先取出,后存入的元素后取出)。 例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。 2. 队列的入口、出口各占一侧。
-
数组
- 概述
Array:是有序的元素序列,数组是在内存中开辟一段连续的空间,并在次空间中放元素
- 特点
特点: (1)查找元素快:可以通过指定的索引快速查询当前元素所在的位置,并访问元素 因为只需要通过要访问的索引,计算地址即可,通过计算之后的地 址,就可以直接找到要查询的元素 (2)增删元素慢: 如果需要增加一个元素,就会重新新建一个容量+1的数组,将数组中的元素复制 到新数组中,再将需要添加的元素添加到指定位置。 如果需要删除一个元素,就重新新建一个容量为-1的数组,将不删除的其他元素 复制到新数组中。
-
链表
- 概述
链表:linkedList,由一系列结点node(链表中每一个元素称为结点)组成,节点可以在运行时动态生成
- 组成及分类
每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储上一个结点或者下一个结点地址的指针域 双向链表就是即可以存储上一个结点也可以存储下一个节点的链表 单向链表是只可以存储下一个节点的链表
- 特点
查找元素慢:想查找某个元素,需要通过开始连接的结点,依次向后查找指定的元素 增删元素快:增加元素只需要修改上一个节点的地址为新节点的地址即可 删除元素只需要修改上一个节点的地址即可
-
哈希表
- 概述
哈希表是通过动态数组和链表组成的一个存储数据的方式
泛型
- 概念
概念:是一个未知的数据类型,是一个参数化类型
- 使用场景
使用场景:需要定义一个类型,类型中的属性所属的数据类型不确定,或者类中的方法 参数和返回值类型并不确定,使用一个符号来表示这个不确定的类型,这个符号就称之 为泛型。
- 使用
泛型的使用: 在使用带着泛型的类型时,需要确定这个泛型是哪一个类型。确定是哪一个类型,类中 就只能使用对应的类型。
- 好处
可以提高代码的扩展性 不需要对获取的每个数据进行强转 提前将问题暴露在编译期
- 注意事项
前后两个泛型要保持一致 如果前面的泛型确定了类型,后面的泛型可以不用写 泛型要定义在类后的尖括号中 泛型只能表示引用数据类型,不能表示基本数据类型
-
泛型类
- 概念
在定义类型的时候使用了泛型的类
- 格式
class 类名<泛型>{
}
- 说明
说明: 如果要在类中使用某个泛型的话,需要先在类上进行声明,声明之后才可以使用 类中使用了几个泛型,需要在类上声明几个泛型 泛型符号:只要是一个合法的标识符即可。T E W Q 泛型在定义的时候不确定,但是在使用的时候就要确定是哪一个类型
-
泛型方法
- 概念
概念:在定义方法的时候,带着泛型的方法。
- 格式
修饰符<泛型的声明>方法名(){
}
- 说明
说明: 如果需要在方法中使用泛型,首先需要在方法上先声明泛型 方法上声明哪一个泛型,就只能使用哪一个泛型 如果这个方法是一个静态方法,必须在方法上声明泛型,不能使用类上声明的泛型 如果这个方法是一个非静态的方法,可以使用类上声明的泛型,也可以自己定义
-
泛型通配符
- 概念
广泛的类型
- 分类
?:类型通配符,所有的类型 ? extends E :类型通配符上限,表示类型E的子类或者E类型 ?super E:类型通配符下限,表示类型E的父类泛型或者E类型
Collections工具类
- 概述
1、概述:本类是JDK提供的操作集合的工具类,类中定义了操作数组中的方法,可以使用 类名直接使用
-
常用方法
- binarySearch(集合名,要查找的元素)
通过二分查找法查找元素key在集合中的索引
- frequency(集合名,要查找的元素)
获取集合中元素出现的次数
- max(Collection c)
求出集合中的最大值
- min(Collection c)
求出集合中的最小值
- reverse(List)
反转集合中的元素顺序
- shuffle(list)
随机排列集合元素的顺序
- sort(list)
将集合中的元素进行升序排列
- swap(list,int i,int j)
交换集合中两个元素的位置
- synchronizedList(list)
将线程不安全的单列集合可以转换为安全的单列集合
- synchronizedMap(Map<K,V>m)
将线程不安全的双列集合转为安全的双列集合
File类
- 概述
概述:可以操作磁盘上文件或者文件夹的类型 可以通过将文件或者文件夹的路径封装为File类对象,通过类中提供的方法操作 此类在io包,需要导包
- 路径
描述文件夹或者文件在计算机上位置的字符串
+ 绝对路径
带着盘符的路径,从根目录开始的路径
+ 相对路径
在父级路径下的一个子级路径
-
构造方法
- File(String pathname)
将参数描述的字符串路径封装为一个file对象
- File(String parent,String child)
将两个字符串拼接之后的路径封装为一个file对象
- File(File parent,String child)
将第一个参数描述的file对象路径,和第二个参数字符串 拼接之后的路径再封装到一个新的对象中
-
创建方法
- creatNewFile()
createNewFile() :创建一个文件
- mkdir()
mkdir() :创建一个文件夹,如果父级路径不存在,就不能创建成功
- mkdirs()
mkdirs() :创建一个文件夹,如果父级路径不存在,连着父级路径一起创建
-
功能
-
删除功能
- delete()
delete() :删除调用者所描述的文件或者文件夹
* 注意 注意:1、不能删除非空文件夹 2、删除后不走回收站
-
重命名
-
renameTo(File dest)
- 注意
参数不是一个字符串,而是一个改名之后的位置字符串所属的file对象 如果在同一个文件夹中,就是重命名 如果在不同的文件夹中,就是剪切
-
-
判断功能
- exits()
exists() :判断调用者描述的文件或者文件夹是否存在
- isDirectory()
isDirectory() :判断调用者是不是一个文件夹
- isFile()
isFile() :判断调用者是不是一个文件
- isAbsolute()
isAbsolute() :判断调用者描述的路径是不是一个绝对路径
-
获取功能
- getAbsolutePath()
getAbsolutePath() :返回绝对路径
- getPath
getPath() :获取相对路径
- getName
getName() :获取调用者描述的文件名或者文件夹名
- length()
length() :获取文件中的字节大小
* 注意 此方法只能适用于文件的对象使用,不适用于文件夹的对象 数据只能再文件中直接存储,不能直接再文件夹的存储
- list()
list() :获取当前调用者目录下所有的文件和文件夹的名称到一个字符串数组中
- listFile()
listFiles() :获取当前调用者目录下所有文件和文件夹的名称之后,再将每个名称字符串 封装为一个个file对象,到一个File数组中。
-
递归
- 概念
概念:递:逐渐的传递 归:归来 回去,回到一种原始的状态 逐渐的回到一种原始的状态 在java语言中,方法自己调用自己,就是递归的使用方式
- 特点
v
- 好处
3、好处: 1、使用简单的逻辑,来完成复杂的问题
- 缺点
4、缺点: 1、使用递归对内存有很大的要求,可能会出现错误 StackOverflowError栈内存溢出异 常 2、使用递归解决问题的效率降低了
IO流
1、凡是操作数据输入和输出的对象所属的类型,都属于IO的范围。
- 概述
1、概述:IO是input和output的缩写。 输入和输出,表示的是数据的输入和数据的输出。
+ 什么是输入和输出
数据的输入和输出就是相对于运行内存来说,数据从其他设备进入到运行内容就是输 入,数据从运行内容到其他设备就是输出。
-
分类
-
功能分类
-
字节流
- 概述
2、字节输入流inputStream 字节输出流outputStream
-
分类
- 字节输入流
1、概述:操作字节信息输入和输出的流对象所属的类型。 2、字节输入流inputStream 字节输出流outputStream
- inputStream * 概述 1、概述:字节输入流,本类是一个抽象父类,不能直接创建对象,需要通过子类创建 * 方法 + read() read() :从流中读取一个字节信息,将信息进行返回。 - 注意 注意:当前方法返回的是一个int类型的数据,而不是一个byte类型 * 原因 原因:默认在读取的字节信息前面加了24个0,强制变为一个int类型 因为读取的信息是一个字节信息 字节范围-128--127,如果读取了一个-1, 可能是读取的数据,也可能是到达文件的末尾,所以为了区分是读取的数据 还是到达了文件的末尾,就默认在读取的数据前+20个0,强制变为正数, 当读取返回了一个-1,肯定是到达了文件的末尾。 + read(byte[] b) 从流对象中一次读取b.length个字节 - 注意 注意:(1)读取的数据存储到了到数组中 - (2)返回值是读取的字节个数 + read(byte[] b,int off,int len) read(byte[] b, int off, int len) :从流中读取指定长度的数据到数组中 + avaliable available() :将流中还没有读取的字节个数进行返回 + close() close() :关闭流资源 * 子类 + FileInputStream - 概述 属于字节输入流的子类,该类的对象可以将磁盘上的文件数据输入到内存中。 - 构造方法 * FileInputStream(File file) (1)FileInputStream(File file):将file文件对象封装为文件字节输入流对象 * FileInoutStream(String str) (2)FileInputStream(String str) :将str字符串所描述的文件封装为字节输入流对象 - 注意事项 不管是传入file对象还是字符串,对应的必须是某一个文件,不能是文件夹 * 原因 原因:因为文件中才可以存储数据,文件夹中不能直接存储数据,所以只能从文件中读 取数据。
-
字节输出流
-
outputStream
- 概述
1、概述:字节输出流,将字节信息从内存中写出到其他设备。也是一个抽象类,需要通过 子类创建对象。
-
方法
- write(int b)
write(int b) :将一个字节信息写出内存
- write(byte[] b)
write(byte[] b) :将一个数组中的信息写出内存
- write(byte[] b,int off,int len)
write(byte[] b, int off, int len) :将数组中的一部分信息写出内容
- close()
close() :关闭流资源
-
子类
-
FileOutPutSream
- 概述
1、概述:文件字节输出流,将字节信息从内存中写出到目标磁盘文件中。
-
构造方法
-
-
-
-