Java
什么是Java?
- Java是全世界最流行的编程语言之一
- 长期霸占IOBE编程语言热度排行榜前三名
1.语法入门
1.1 常量和变量
-
常量
-
常量是一种特殊的变量,它的值被设定后,在程序运行过程中不允许改变,一般用大写字符
```java
语法:final 常量名 = 值;如:final String LOVE = ‘java‘;
注意:必须要在常量声明的时候就对其进行初始化,否则会出现编译错误。常量一旦初始化后就无法再改动
字符型常量的三种表现形式:
1.字符常量是用单引号(‘ ’)括起来的单个字符,涵盖世界上所有书面语的字符。例如:char c1 = ‘a‘; char c2 = ‘中‘; char c3 = ‘9‘;
2.Java中还允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量。例如:char c3 = ‘\n’; // ‘\n‘表示换行符
3.直接使用 Unicode 值来表示字符型常量:‘\uXXXX’。其中,XXXX代表一个十六进制整数。如:\u000a 表示 \n
```
-
变量
变量是内存中的一个存储区域,该区域有自己的名称(变量名)和类型(数据类型),Java中每个变量必须先声明,后使用, 该区域的数据可以在同一类型范围内不断变化。
- 变量的三个元素:变量类型,变量名,变量值
-
变量名的命名规则
- 满足标识符命名规则
- 符合驼峰法命名规范
- 尽量简单,做到见名知意
- 变量名的长度没有限制
1.1.1 标识符
- 标识符的命名规则
- 标识符可以由字母,数字,下划线(_)和美元符($)组成,不能以数字开头
- 标识符严格区分大小写
- 标识符不能是java关键字和保留字
- 标识符的命名最好是能反映其作用
1.1.2 关键字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zMQxrgL-1662885657716)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220408152503030.png)]
1.1.3 数据类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DS3qgaR7-1662885657717)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220408153659640.png)]
- 基本数据类型
- 基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。有如下特点:
数据类型 | 说明 | 字节 |
---|---|---|
byte | 字节型 | 1 |
short | 短整型 | 2 |
int | 整型 | 4 |
long | 长整型 | 8 |
float | 单精度浮点型 | 4 |
double | 双精度浮点型 | 8 |
char | 字符型 | 2 |
boolean | 布尔型 | 1 |
-
字符型字面值
- 字符型字面值用单引号内的单个字符表示如:‘a’,‘b’,'$'等
-
ASCII码
- 使用七位或八位二进制数组合来表示128或256种可能的字符(七位二进制数字组合----标准ASCII码,8位二进制组合-----扩展ASCII码)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sp69zUFC-1662885657717)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220408155825255.png)]
-
unicode编码
- Unicode又称为统一码、万国码、单一码,是国际组织制定的旨在容纳全球所有字符的编码方案,包括字符集、编码方案等,它为每种语言中的每个字符设定了统一且唯一的二进制编码,以满足跨语言、跨平台的要求
-
类型转换
- 类型转换分为自动类型转换和强制类型转换
- 自动类型转换
- 类型转换分为自动类型转换和强制类型转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgihLZfH-1662885657718)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220408165956326.png)]
基本数据类型
基本的数据类型有:三大类8种
.基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。有如下特点:
1、基本数据类型的值是不可变的(我们不能给基本数据类型添加属性和方法);
2、基本数据类型的比较是值的比较(只有他们的值相等的时候才是相等的);
3、基本数据类型的变量是存放在栈里面的
引用数据类型
除了基本数据类型其余的都是引用数据类型了,也可以说就是对象。引用数据类型有三大类;
对象是属性和方法的集合,也就是说引用数据类型可以拥有属性和方法,属性又可以包括基本数据类型和引用数据类型。有如下特点:
1、引用数据类型可以拥有属性和方法,且值是可变的;
2、引用数据类型的值是同时保存在栈内存和堆内存的对象
1.2 java运算符
- 算术运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 条件运算符
- 位运算符
1.2.1 算术运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uybAVqjv-1662885657718)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409163747216.png)]
自增自减运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IqBGJdQS-1662885657719)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409164707706.png)]
1.2.2赋值运算符
- 格式:变量=表达式
- 例:int n=3; //将3赋值给变量n
- 注意:赋值运算符是从右往左运行
复合赋值运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DnifsmcV-1662885657719)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409165659793.png)]
1.2.3 关系运算符
- 比较运算符用于判断两个数据的大小
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mPDzSjeB-1662885657720)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409165954692.png)]
!!!注意 =是赋值 == 是等于
字符做比较,比较的是两个字符的ASCII值
浮点数于整数做比较只要值相当结果为true 例如 float f=5.0; long l=5; f==l;(true)
1.2.4 逻辑运算符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m3pRziq0-1662885657720)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409170809792.png)]
-
&&运算符又叫短路运算符,如果第一个表达式的值就能决定表达式最后的结果,运算符右边的表达式就不再计算了
-
和&&运算符一样。||运算符又叫短路运算符,如果第一个表达式的值就能决定表达式最后的结果,运算符右边的表达式就不再计算了
-
!运算符 取反
1.2.5 条件运算符
-
java中条件运算符是三目运算符
-
语法:
-
布尔表达式?表达式1:表达式2
-
当布尔表达式的值为true,则返回表达式1的值,否则返回表达式2的值
1.2.6运算符优先级
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FlfQOPww-1662885657720)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220409173657443.png)]
从高到低
1.3 选择结构
1.3.1 多重if结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcWDnMRo-1662885657721)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410101721920.png)]
Scanner sc = new Scanner(System.in); //从键盘接受数据
int score = sc.nextInt(); //nextInt 方式接受数字
if (score>=90){ //成绩大于等于90分输出优
System.out.println("优");
}else if (score>=80 && score<90){ //成绩大于等于80分且小于90分,输出良
System.out.println("良");
}else if(score>=60 && score<80){ //成绩大于等于60分小于80分,输出中
System.out.println("中");
}else if(score<60){ //成绩小于60分,输出不及格
System.out.println("不及格");
}
1.3.2 嵌套if结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yuvo5m9A-1662885657721)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410102145415.png)]
1.3.3 switch结构
if和switch的区别
-
if结构
- 判断条件是布尔类型
- 判断条件是一个范围
-
switch结构
- 判断条件是常量值
switch语法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEwyIknN-1662885657721)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410102856991.png)]
break——跳出从循环结构
default——表达式找不到匹配的值
case——找到配等的值
案例
Scanner sc = new Scanner(System.in);
int date = sc.nextInt();
switch (date){
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("输入不合法,超出范围");
}
!!!注意如果不打break;终止循环结果会打印从符合条件一直输出到最后
如果输入类型是int 输入字符串a 报错:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jLFWyqyk-1662885657722)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410103959758.png)]
字符串写法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxUnxrHs-1662885657722)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410104114659.png)]
注意!!!java中区分大小写
2.循环,数组与方法
2.1 循环结构
- while循环
- do-while循环
- for循环
- 循环嵌套
- break语句
- continue语句
2.1.1 while循环
语法格式
while(循环条件){
语句;
}
案例1 输出小于5的值
int n=1;
while(n<5){ //n小于5时结束循环
System.out.println(n); //打印数据
n++; //n值递加
}
案例2 1到5的累加和
int i=1;
int num=0; //sum是存放和的变量
while(i<=5){//n小于5时结束循环
num+=i; //累加每循环一次就+i
i++; //n值递加
}
System.out.println(num); //打印结果
案例3 循环输出英文字母
char ch='a';
int count = 1; //控制换行
while (ch <='z'){
System.out.print(ch+" ");
if (count % 13== 0){
System.out.println();
}
ch++;
count++;
}
System.out.println(count);
2.1.2 do-while循环
注意事项:
- do-while循环至少执行一次
- 循环条件后的分号不能丢
执行过程:先执行循环体中的内容然后执行循环条件如果条件满足则继续循环
int n=1;
do{
System.out.println(n);
n++;
}while(n<5);
案例 1 猜数字游戏
int number=7; //设置要猜测的值
int count; //变量
do {
Scanner sc = new Scanner(System.in); //键盘输入
count=sc.nextInt(); //数字输入类型
System.out.println("请输入一个数字")
if (count>7){ //当输入的值大于 7打印猜大了
System.out.println("猜大了");
}else if (count<7){ //当输入的值小于 7打印猜小了
System.out.println("猜小了");
}
}while (number!=count); //循环条件键盘输入的值不等于要猜测的值
System.out.println("恭喜你猜中了"); //当值相等打印猜中了
猜测的值可以设置为随机数Math.random(); 返回一个[0,1)的数字0-1
2.1.3 for循环
语法格式
for(表达式1;表达式2;表达式3){
语句;
}
循环顺序[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ivlwHQMV-1662885657723)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410171525960.png)]
2.1.4 嵌套循环
案例
int num=1;
int count=1;
while (num<5){
count=1; //外循环每循环一次count归1 不然内循环完 外循环将不在进行内循环
while (count<=num){
System.out.print("*"); 打印*
count++;
}
System.out.println(); //换行
num++; //值++
}
结果[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qCBy1xG2-1662885657723)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220410175633149.png)]
2.1.5 break语句
- break语句可以结束当前循环的执行
- 执行完break语句后,循环体中位于break语句后面就不会被执行
- 在多重循环中,break语句只向外跳一层
注意break是跳出当前循环
2.1.6 continue语句
- continue语句只能用在循环里
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FehHhjJr-1662885657723)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220411114420821.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sg7w4gvd-1662885657724)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220411114428107.png)]
2.1.7 debug入门
调试的作用:
让程序员能看清程序每一步的效果,在需要查看结果的时候,使用debug查看实际结果是否与预期结果一致。
2.2 数组
- 数组是相同类型的数据按顺序组成的一种引用数据类型
2.2.1 一维数组
学习内容
-
一维数组
- 声明
- 创建
- 初始化
- 元素的引用
- 长度
-
语法格式:
- 数据类型[] 数组名;
- 数据类型 数组名[];
-
数组创建
-
语法格式一:先声明后创建
- 数据类型[] 数组名;
- 数组名=new 数据类型[数组长度];
- int[]arr;
- arr=new int[10];
-
语法格式二:声明的同时创建数组
- 数据类型[]数组名 = new 数据类型[数组长度];
- int []arr=new int[10];
-
注意:长度必须指定
- 数组的初始化
- 声明数组的同时给数组赋值,叫做数组的初始化
例:
int[] arr={1,2,3,4,5,6,7,8,9,10};
数组的长度就是初始化时所给数组元素的个数
案例:求整型数组的累加和
//求整型数组的累加和
//定义整型数组
int [] arr=new int[5];
Scanner sc = new Scanner(System.in); //键盘输入
for (int i = 0; i <arr.length ; i++) { //给数组循环赋值
System.out.println("请输入第"+(i+1)+"个元素");
arr[i]=sc.nextInt(); //赋值
}
System.out.println("数组元素的内容为:");
for (int i = 0; i <arr.length ; i++) {
//打印数组的数据
System.out.println(arr[i]);
}
案例二:累加和
int num=0;
//求元素的累加和
for (int i = 0; i <arr.length ; i++) {
num+=arr[i];
}
System.out.println("数组元素累加和="+num);
2.2.2 算法 冒泡排序
int [] arr={34,53,12,32,56,17}; // 定义一个int类型数组
int temp; //定义临时变量
System.out.println("排序前:");
for (int i : arr) {
System.out.println(i);
}
for (int i = 0; i <arr.length-1 ; i++) { //需要进行排序的次数为arr.length-1次
for (int j = 0; j <arr.length-i-1 ; j++) {
if (arr[j]>arr[j+1]){ // 比较第一对相邻的元素。判断第一个元素是否大于第二个元素如果是则交换
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println("排序后:");
for (int i : arr) {
System.out.println(i);
}
2.2.3 二维数组
-
二维数组的声明的创建
-
二维数组的声明
- int[] [] intArray;
- float floatArray[] [];
- double[] doubleArray[];
-
二维数组的创建
- intArray = new int[3] [3];
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GaK7uxvG-1662885657725)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220413093738278.png)]
-
-
二维数组的初始化
- int[] [] num={{1,2,3},{4,5,6},{7,8,9}};
2.3 方法
2.3.1 方法声明
- 语法格式:
访问修饰符 返回类型 方法名(参数列表){
方法体
}
- 方法分类
- 根据方法是否带参数,是否返回值,可分四类
- 无参无返回值方法
- 无参带返回值方法
- 带参无返回值方法
- 带参带返回值方法
- 根据方法是否带参数,是否返回值,可分四类
无参无返回值方法
public class Test01 {
public static void main(String[] args) {
Test01 test01 = new Test01();
test01.run();
}
public void run(){
System.out.println("*********");
}
}
无参有返回值方法
public static void main(String[] args) {
Rectangle rectangle = new Rectangle();
int area = rectangle.area();
System.out.println(area);
}
//求长方形面积的方法
public int area(){
int length=10;
int width=5;
int area=length*width;
return area;
}
带参无返回值方法
public class MaxDemo {
public static void main(String[] args) {
MaxDemo maxDemo = new MaxDemo();
maxDemo.max(3,5);
}
//求最大值方法
public void max(float a,float b){
float max;
if (a>b){
max=a;
}else {
max=b;
}
System.out.println("最大值为"+max);
}
}
带参有返回值方法
public static void main(String[] args) {
FacDemo facDemo = new FacDemo();
int i = facDemo.fac(5);
System.out.println(i);
}
//求阶乘的方法
public int fac(int a){
int s=1;
for (int i = 1; i <=a ; i++) {
s*=i;
}
return s;
}
2.3.2 方法重载
方法重载的规则
- 方法名称必须相同。
- 参数列表必须不同。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以称为方法的重载。
2.3.4 基本数据类型和引用数据类型传值
- 基本数据类型的传值
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
int a = 10;
int b = a;
a ++ ;
system.out.println(a); // 11
system.out.println(b); // 10
此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,
这两个变量可以参加任何操作而相互不受影响。
也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FFkfcV6p-1662885657725)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220417131003943.png)]
- 引用数据类型的传值
public static void main(String[] args) {
int[]arr={1,2,3,4,5,6,7};
System.out.println("方法调用前数组的值为:");
for (int i : arr) {
System.out.println(i);
}
System.out.println();
ArrayDemo arrayDemo = new ArrayDemo();
arrayDemo.updateArray(arr);
System.out.println("方法调用后数组的值为:");
for (int i : arr) {
System.out.println(i+" ");
}
System.out.println();
}
public void updateArray(int[]a){
a[3]=15;
System.out.println("数组a的值为:");
for (int i : a) {
System.out.println(i+" ");
}
System.out.println();
}
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gI1AIWIg-1662885657726)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220417125932737.png)]
基本数据类型的值存在栈中我们不能给基本数据类型添加属性和方法,基本数据类型的值是不可变的。
而引用数据类型同时存放于栈内存和堆内存中,假如有以下几个对象:
var person1 = {name:‘jozo’};
var person2 = {name:‘xiaom’};
var person3 = {name:‘xiaoq’};
则这三个对象的在内存中保存的情况如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crqphu6M-1662885657726)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220417130313618.png)]
引用数据类型在作比较时比较的是两个对象的堆内存中的地址是否相同
2.3.5 可变参数列表
可变参数累加和
public static void main(String[] args) {
sum(1);
sum(1,2);
sum(1,2,3);
}
public static void sum(int... n){
int sum=0;
for (int i : n) {
sum+=i;
}
System.out.println("sum="+sum);
}
注意!可变参数必须是参数的最后一个
3.面向对象
3.1 封装
3.1.1 new关键字
- 实例化对象的过程可以分为两部分
- 声明对象 Cat one
- 实例化对象 new Cat();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BzCB09Dr-1662885657726)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418172148633.png)]
声明对象是再栈里面 实例化对象是在堆里面
cat类
public class Cat {
//成员属性 昵称,年龄,体重,品种
String name; // 昵称
int month; //年龄 int类型默认值0
double weight; //体重 double类型默认值0.0
String species; //品种
//跑动的方法
public void run(){
System.out.println("小猫快跑");
}
public void run(String name){
System.out.println(name+"快跑");
}
//吃东西的方法
public void eat(){
System.out.println("小猫吃鱼");
}
}
实现类
public class CatTest {
public static void main(String[] args) {
// 对象实例化
Cat one = new Cat();
//测试
one.eat();
one.run();
one.name="花花";
one.month=2;
one.weight=1000;
one.species="英国短毛猫";
System.out.println("昵称:"+one.name);
System.out.println("年龄:"+one.month);
System.out.println("体重:"+one.weight);
System.out.println("品种:"+one.species);
one.run(one.name);
}
}
当再次创建一个对象two操作如下
cat two=one;
时 one和tow 这两个对象在栈中用的是同一个地址值去堆内存中进行查找
当one修改了属性tow的属性也随之改变;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NMqobbVU-1662885657727)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418200407563.png)]
3.1.2 类和对象
-
类
- 抽象的概念
- 模板
-
对象
- 一个看得到,摸得着的具体实体
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u51cE9mk-1662885657727)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418182124465.png)]
对象的属性和方法
- 属性:对象具有的各种静态特征 ——对象有什么
- 方法:对象具有的各种动态特征——对象做什么
类和对象的关系
- 类是抽象的概念,仅仅是模板
- 对象是一个你能看得到,摸得着的具体实体
- 类是对象的类型
- 对象是特定类型的数据
- 具体开发过程中,先定义类再实例化对象
3.1.3 单一职责原则
单一职责原则
- 单一职责原则,也称为单一功能原则
- 英文Single Responsibility Principle 缩写SRP
- 是面向对象设计中的一个重要原则
- 一个类,应该有且只有一个引起变化的原因
- 在程序设计中,尽量把不同的职责,放在不同的职责中,即把 不同的变化原因,封装到不同的类中.
3.1.4 构造方法
1,构造方法与类同名且没有返回值
2,构造方法的语句格式
3,只能在对象实例化的时候调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4H2X1Lxi-1662885657727)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418203234659.png)]
4,当没有指定构造方法时,系统会自动添加无参的构造方法
5,当有指定构造方法,无论是有参,无参的构造方法,都不会自动添加无参的构造方法
6,一个类中可以有多个构造方法
3.1.5 this关键字
- this:当前对象的默认引用
- this的使用
- 调用成员变量,解决成员属性和局部变量同名冲突
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-og83Zp3D-1662885657728)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418211921038.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hxdzxX4G-1662885657728)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418211927615.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SFdnErbr-1662885657728)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418211932440.png)]
调用重载的构造方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tyYH13Rc-1662885657729)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220418212018466.png)]
3.1.6 java封装
封装
- 将类的某些信息隐藏在类内部,不允许外部程序直接访问
- 通过该类提供的方法来实现对隐藏信息的操作和访问
- 隐藏对象的信息
- 留出访问的接口
特点:
1,只能通过规定的方法访问数据
2,隐藏类的实例细节,方便修改和实现
private私有的只有当前类能够调用被private修饰的变量其他类调取不到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTYXRiUP-1662885657729)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220419201802939.png)]
3.1.7 static关键字
1,static+属性——静态属性
2,static+方法——静态方法
3,static+类——不存在
4,static+方法内局部变量——不存在
静态成员随类加载产生,直至类销毁才回收
注意!
1,可以直接调用同类中的静态成员
2,不可以直接调用同类中的非静态成员
3,可以通过实例化对象后,对象调用的方式完成非静态成员调用
4,静态方法中不能使用this关键字
3.1.8 包
作用:
1,管理java文件
2,解决同名文件冲突
3.4.1 定义包
语法:
package 包名;
例:package com.imooc.animal;
注意:
1,必须放在java源文件中的第一行
2,一个java源文件中只能有一个package语句
3,包名全部英文小写
4,命名方式:域名倒叙+模块+功能
3.4.2 导入包
语法:
import 包名.类名;
例:
导入包中全部类:
import com.imooc.*;
导入包中指定类:
import com.imooc.animal.Cat;
常用系统包
java.lang 包含java语言基础的类
java.util 包含java语言中各种工具类
java.io 包含输入,输出相关功能的类
3.1.9 代码块
1,通过{}可以形成代码块
2,方法内的代码块称为:普通代码块
3,类内的代码块称为:构造代码块
4,构造代码块前+static:静态代码块
代码块执行顺序
1,无论实例产生多少对象,静态代码块只执行一次
2,构造代码块随实例话过程调用
3,普通代码块随方法调用执行
3.2 继承
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FwNDHxRa-1662885657729)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220429085257440.png)]
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avchQOTd-1662885657730)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220429085316110.png)]
- 一种类与类之间的关系
- 使用已经存在的类的定义作为基础建立新类
- 新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类
!注意一个子类只能继承一个父类,且之类只能继承父类非私有成员
代码实现
父类
package 面向对象;
public class Animal {
//公共的属性和方法
private String name; //昵称
private int month; //月份
private String species; //品种
public void eat(){
System.out.println(this.getName()+"在吃东西");
}
public Animal() {
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", month=" + month +
", species='" + species + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public Animal(String name, int month, String species) {
this.name = name;
this.month = month;
this.species = species;
}
}
monkey子类
package 面向对象;
public class Monkey extends Animal {
private double weight; //体重
public Monkey() {
}
public Monkey(double weight) {
this.weight = weight;
}
public Monkey(String name, int month, String species, double weight) {
super(name, month, species);
this.weight = weight;
}
public void run(){
System.out.println(this.getName()+"是一只"+this.getSpecies()+",他在快乐的奔跑");
}
}
dog子类
package 面向对象;
public class Dog extends Animal {
private String sex; //性别
public void sleep(){
System.out.println(this.getName()+"现在"+this.getMonth()+"月大的,他在睡觉");
}
public Dog() {
}
public Dog(String sex) {
this.sex = sex;
}
public Dog(String name, int month, String species, String sex) {
super(name, month, species);
this.sex = sex;
}
@Override
public String toString() {
return "Dog{" +
"sex='" + sex + '\'' +
'}';
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Dog(String name, int month, String species) {
super(name, month, species);
}
}
!父类不能调用子类的方法
!子类不能调用父类的私有方法
- 继承的特点
- 1,利于代码复用
- 2,缩短开发周期
3.2.1 方法重写
语法规则
- 在子类中定义
- 方法名
- 参数类型,顺序,个数
方法重写和方法重载的区别
-
方法重写
- 在满足继承关系的子类中
- 方法名,参数个数,顺序,类型与父类,返回值相同
- 访问修饰符的限定范围大于等于父类方法
-
方法重载
- 在同一个类中
- 方法名相同
- 参数个数,顺序,类型不同
- 返回值和访问修饰符任意
3.2.3 访问修饰符
- 公有的:public
- 私有的:private
- 受保护的:protected
- 默认
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QsYIXpfp-1662885657730)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220501102928576.png)]
3.2.4 实例化顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G2XQNrls-1662885657730)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220501111058825.png)]
3.2.5 super关键字
• 子类的构造的过程中必须调用其父类的构造方法
• 如果子类的构造方法中没有显示调用父类的构造方法,则系统 系默认调用父类无参的构造方法
• 如果子类构造方法中既没有显式调用父类的构造方法,而父类 又没有无参的构造方法,则编译出错
• 使用super调用父类指定构造方法,必须在子类的构造方法的 第一行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXjqElYS-1662885657731)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220501111221976.png)]
3.2.6 object类
- object类所有类的父类
- 一个类没有使用extends关键字明确标识继承关系则默认继承object类(包括数组)
- Java 中的每个类都可以使用object中定义的方法
object类常用方法
方法 | 说明 |
---|---|
toString() | 返回当前对象本身的有关信息 |
equals() | 比较两个对象是否是同一个对象 |
hashCode() | 返回该对象的哈希代码值 |
getClass() | 获取当前对象所属的类信息,返回class对象 |
3.2.7 final关键字
1,修饰类表示不允许被继承
2,修饰方法表示不允许被子类重写
-final修饰的方法可以被继承
-不能修饰构造方法
3,修饰变量表示不允许修改
- 方法内部的局部变量 》在使用之前被初始化赋值即可
- 类中成员变量 》 只能在定义时或者构造代码块,构造方法中进行初始化设置
- 基本数据类型的变量 》 初始赋值之后不能更改
- 引用类型的变量 》 初始化之后不能再指向另一个对象,但指向的对象的内容是可变的
4,可配合static使用 当作不可修改的全局变量
5,使用 final修饰可以提高性能但会降低可扩展性
3.2.8 单例模式
设计模式
-
设计模式(Design pattern)是一套被反复使用,多数人知晓的经过分类编目的,代码设计经验的总结。
-
设计模式是软件开发人员再软件开发过程中面临的一般问题的解决方案
设计模式的种类
- 面向对象的设计模式很多,但大家认为这23个模式是其他模式的基础
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WtxrvlJe-1662885657731)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220502204650742.png)]
单例模式要点:
-
- 某个类只能有一个实例
- 必须自行创建实例
- 必须自行向整个系统提供这个实例
单例模式实现:
-
- 只提供私有的构造方法
- 含有一个该类的静态私有对象
- 提供一个静态的共有方法用于创建,获取静态私有对象
代码实现方式:
- 饿汉式
- 懒汉式
饿汉式
代码实现
package 单例模式;
//饿汉式:创建对象实例的时候直接初始化
// 空间换时间
public class SingletonOne {
// 1. 创建类中私有构造
private SingletonOne(){
}
// 2. 创建该类型的私有静态实例
private static SingletonOne instance = new SingletonOne();
// 3. 创建公有静态方法返回静态实例对象
public static SingletonOne getInstance(){
return instance;
}
}
懒汉式
代码实现
package 单例模式;
//懒汉式
public class SingletonTwo {
// 1 创建私有的构造方法
private SingletonTwo(){
}
//2 创建静态的该类实例对象
private static SingletonTwo singletonTwo;
//3 创建开放的静态方法提供实例对象
public static SingletonTwo getInstance(){
if (singletonTwo==null){
singletonTwo=new SingletonTwo();
}
return singletonTwo;
}
}
饿汉式对比懒汉式
-
饿汉式
- 在类加载时就创建实例,第一次加载速度块
- 饿汉式:空间换时间
-
l懒汉式
- 懒汉式第一次使用时进行实例化,第一次加载慢
- 懒汉式:时间换空间
-
饿汉式线程安全;懒汉式存在线程风险 解决方案:
-
1、同步锁 2、静态内部类 3、双重校验锁 4、枚举
单例模式的优点:
- 在内存中只有一个对象,节省内存空间
- 避免频繁的创建销毁对象,提高性能
- 避免对共享资源的多重占用
缺点
- 扩展比较困难
- 如果实例化后的对象长期不利用,系统将默认为垃圾进行回收, 造成对象状态丢失
适用场景
- 创建对象时占用资源过多,但同时又需要用到该类对象
- 对系统内资源要求统一读写,如读写配置信息
- 当多个实例存在可能引起程序逻辑错误,如号码生成器
3.3 多态
- 多态(polymorphism)按字面的意思就是“多种状态” ,是面向对象的程序设计语言的最核心的特征。
- 从一定角度来看,封装和继承几乎都是为了多态而准备的。
多态的分类
-
- 编译时多态(设计时多态):方法重载
- 运行时多态:java运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态
我们平时所说的多态,多指运行时多态
程序中的继承
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WI1Kk53N-1662885657731)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220503171631506.png)]
3.3.1 类型转换
Animal类
package 面向对象.多态;
public class Animal {
public String name;
public int month;
public void eat(){
System.out.println("动物们在吃东西");
}
public Animal(String name, int month) {
this.name = name;
this.month = month;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public Animal() {
}
}
cat类
package 面向对象.多态;
public class Cat extends Animal {
private double weight;
public Cat() {
}
public Cat(double weight) {
this.weight = weight;
}
public Cat(String name,int month,double weight){
super(name,month);
this.weight=weight;
}
public void run(){
System.out.println("小猫在快乐的奔跑");
}
public void eat(){
System.out.println("猫吃🐟");
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
dog类
package 面向对象.多态;
public class Dog extends Animal {
private String sex; //性别
public Dog() {
}
public Dog(String name, int month, String sex) {
super(name, month);
this.sex = sex;
}
public void eat(){
System.out.println("张更在吃大便");
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
测试类 向上类型转换(Upcast):将子类型转换为父类型
package 面向对象.多态;
public class Test01 {
public static void main(String[]args){
Animal one = new Animal();
Animal tow = new Cat();
Animal three = new Dog();
one.eat();
tow.eat();
three.eat();
}
}
- 隐式/自动类型转换,是小类型到大类型的转换
- 对于向上的类型转换,不需要显示指定,既不需要加上前面的小括号和父类类型名
instanceof
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGpZWnoB-1662885657732)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220503195730461.png)]
3.3.2 抽象类
应用场景:
某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
- abstract也可用于方法------抽象方法
- 抽象方法没有方法体
- 抽象方法必须在抽象类里
- 抽象方法必须在子类中被实现,除非子类是抽象类
抽象类&抽象方法
使用规则
- abstract定义抽象类
- 抽象类不能直接实例化,只能被继承,可以通过向上转型完成对象实例
- abstract定义抽象方法,不需要具体实现
- 包含抽象方法的类是抽象类
- 抽象类中可以没有抽象方法
- 子类如果没有重写父类所有的抽象方法,则也要定义为抽象类
- abstract 不能与 static,final,private共存
- 抽象方法在子类实现时访问权限必须大于等于父类方法
4. 常用工具类
4.1 异常
什么是异常
- 异常是程序上的错误
- 在程序运行过程中,意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常
错误再我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误
4.1.1 异常的分类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfxJVKpT-1662885657732)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220507093329849.png)]
- throwable有两个重要的子类:Exception和error
Error
-
Error是程序无法处理的错误,表示运行应用程序中较严重问题,大多数错误与代码编写者执行的操作无关,而表示代码运行时jvm出现的问题
- 例如,java虚拟机运行错误(Virtual MachineError),当jvm不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError
-
这些错误是不可查的,因为他们在应用程序的控制和处理能力之外而且绝大多数是程序运行时不允许出现的状况。
-
对于设计合理的应用程序来说,即使确实发生了错误,本质上也不该试图去处理它所引起的异常状况
-
因此我们编写程序时不需要关心这类异常
Exception
-
Exception是程序本身可以处理的异常。异常处理通常指针对这种类型异常的处理
-
Exception类的异常包括checked exception 和unchecked exception
-
unchecked exception
- unchecked exception:编译器不要求强制处置的异常
- 包含runtimeException类及其子类异常
- 如NullPointerException(空指针异常) IndexoutofboundsException(下标越界异常)等,这些异常是unchecked exception。
java编译器不会检查这些异常,在程序中可以选择捕获处理,也可以不处理,照样正常编译通过
- checked exception
- checked exception:编译器要求必须处置的异常
- 是runtimeException 及其子类以外,其他Exception类的子类
- 如IOException , SQLException等
java编辑器会检查这些异常,当程序中可能出现这类异常时,要求必须进行异常处理,否则编译不会通过。
4.1.2 异常处理
- 在java应用程序中,异常处理机制为:抛出异常,捕捉异常
- 当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统
- 异常对象中包含了异常类型的异常出现时的程序状态等异常信息
- 运行时系统负责寻找处置异常的代码并执行
异常处理
- 通过5个关键字来实现:try,catch,finally,throw,throws
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V09ChLSu-1662885657732)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220507111613107.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHt3510I-1662885657733)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220507111646400.png)]
- 使用try-catch块捕获异常
public void method(){
try{
//代码块
}catch{
//对异常进行处理的代码块
}
//代码块
}
使用try-catch块捕获并处理异常-无异常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-084SAXQ9-1662885657733)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220507111938445.png)]
使用try-catch块捕获并处理异常-有异常并能正常匹配处理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tqeM5mzQ-1662885657733)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220507112022775.png)]
使用try-catch块捕获并处理异常-有异常不能正常匹配处理
-
多重catch块
- 一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch语句结束,其他catch子句不再有匹配和捕获异常类型的机会
- 对于多个catch子句的异常程序而言,应该尽量将捕获底层异常类catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句放后面,否则,捕获底层异常类的catch子句将可能被屏蔽
-
引发多种类型的异常
- 排序catch语句的顺序:先子类后父类
- 发生异常时按顺序逐个匹配
- 只执行第一个与异常类型匹配的catch语句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HasfxwPN-1662885657733)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220508103522753.png)]
4.1.3 常见的异常类型
异常类型 | 说明 |
---|---|
Exception | 异常层次结构的父类 |
ArithmeticException | 算术错误情形,如除零异常 |
ArrayIndexOutOfBoundsException | 数组下标越界 |
NullPointerException | 尝试访问null对象成员 |
ClassNotFoundException | 不能加载所需的类 |
lllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 对象强制类型转换出错 |
NumberFormatException | 数字格式转换异常,如“abc”转换成数字 |
throws关键字
可以通过throws声明将要抛出何种类型的异常,通过throw将产生的异常抛出
- throws
- 如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws字句来声明抛出异常
- 例如:汽车在运行时可能会出现故障,汽车本身没办法处理这个故障那就让开车的人来处理
- throws语句用在方法定义时声明该方法要抛出异常的类型
- 当方法抛出异常列表中的异常时,方法将不对这些类型及其子类类型异常左处理,而抛向调用该方法的方法,由他去处理
throws的使用规则
- 如果是不可查异常(uncheck exception),即Error,RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能顺利通过,但在运行时会被系统抛出
- 如果一个方法中可能出现可查异常,使用try-catch语句捕获,要么用throws字句声明将它抛出,否则会导致编译错误
- 当抛出了异常,则该方法的调用者必须处理或者重新抛出该异常
- 当子类重写父类抛出异常的方法时,声明的异常必须是父类方法所声明异常的同类或子类
throw 关键字
- throw用来抛出一个异常
- 例如:throw new IOException();
- throw 抛出的只能够是可抛出类throwable 或者其子类的实例对象
- 例如:thorw new String(“出错了”); 是错误的
4.1.4 自定义异常
- 使用java内置的异常类可以描述在编程时出现的大部分异常情况
- 也可以通过自定义异常描述特定业务产生的异常类型
- 所谓的自定义异常,就是定义一个类,去继承Thorwable类或它的子类
4.2 java包装类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZZrA1Zc-1662885657734)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220508112036088.png)]
4.2.1 包装类与基本数据类型
-
装箱:把基本数据类型转换成包装类
-
自动装箱
-
手动装箱
-
//1.自动装箱 int t1=2; Integer t2=t1; //2.手动装箱 Integer t3=new Integer(t1);
-
-
拆箱:把包装类转换成基本数据类型
- 自动拆箱
- 手动拆箱
//1.自动拆箱
Integer t5=t1;
int t6=t5;
//2.手动拆箱
int t7=t5.intValue();
4.2.2 字符串与基本数据类型
- 基本数据类型转换为字符串
- 使用包装类的toString()方法
- 字符串转换为基本数据类型
- 自动拆箱调用包装类的parsexxx()静态方法
- 调用包装类的valueOf()方法转换为基本类型的包装类自动拆箱
4.3 字符串
String
String的常用方法
方法 | 说明 |
---|---|
int length() | 返回当前字符串的长度 |
int indexOf(int ch) | 查找ch字符在该字符串第一次出现的位置 |
int indexOf(string str) | 查找str子字符串在该字符串中第一次出现的位置 |
int lastIndexOf(int ch) | 查找ch字符在该字符串最后一次出现的位置 |
int lastIndexOf(String str) | 查找str子字符串在该字符串中最后一次出现的位置 |
String substring(int beginIndex) | 获取从beginIndex位置开始到结束的子字符串 |
String substring(int beginIndex,int endIndex) | 获取从beginIndex位置开始到endIndex位置的子字符串(包头不包尾) |
String trim() | 返回去除了前后空格的字符串 |
boolean equals(object obj) | 将该字符串与指定对象比较,返回true或false |
String toLowerCase() | 将字符串转换成小写 |
String toUpperCase() | 将字符串转换成大写 |
char charAt(int index) | 获取字符串中指定位置的字符 |
String[] split(String regex,int limit) | 将字符串分割为子字符串阿,返回字符串数组 |
byte[] getBytes() | 将该字符串转换为byte数组 |
StringBuilder
String和StringBuilder的区别:
String具有不可变性,而StringBuilder不具备
建议:
当频繁操作字符串时,使用StringBuilder
- StringBuilder和StringBuffer
- 二者基本相似
- StringBuffer是线程安全的,StringBuilder则没有,所以性能略高
- 在执行速度方面的比较:StringBuilder >StringBuffer
StringBuilder类的常用方法
方法 | 说明 |
---|---|
StringBuilder append(参数) | 追加内容到当前StringBuilder对象的末尾 |
StringBuilder insert(位置,参数) | 将内容插入到StringBuilder对象的指定位置 |
String toString() | 将StringBuilder对象转换为String对象 |
int length() | 获取字符串的长度 |
4.4 集合
- 数组存储的不足与缺陷
- 长度开始必须执行,而且一旦指定,无法修改
- 保存的必须为同一类型的元素
- 使用数组进行增加/删除比较麻烦
- 集合的好处
- 可以动态保存多个对象使用方便
- 提供了一系列方便的操作对象的方法,如add,remove,set,get等
- 使用集合增加/删除比较方便
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W0LOi5ev-1662885657734)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220517171050973.png)]
List
- List是元素有序并且可以重复的集合,称为序列
- List可以精准的控制每个元素的插入位置,或删除某个位置的元素
- List的两个主要实现类是ArrayList和LinkedList
常用方法
方法名 | 作用 |
---|---|
add(Object element) | 像列表尾部添加指定的元素 |
size() | 返回列表中的元素的个数 |
get(int index) | 返回列表中指定位置的元素,index从0开始 |
add(int index,Object element) | 在列表的指定位置插入指定元素 |
set(int i,Object element) | 将索引i位置元素替换为元素element并返回被替代的元素 |
clear(); | 从列表移除所有元素 |
isEmpty(); | 判断列表是否包含元素,不包含元素则返回true,否则返回false |
contains(Object o) | 如果列表包含指定的元素,则返回trye |
remove(int index); | 移除列表中指定位置的元素,并返回被删元素 |
remove(object o) | 移除集合中第一次出现的指定元素,移除成功返回true,移除失败返回false |
iterator() | 返回按适当顺序在列表的元素上进行迭代的迭代器 |
ArrayList
- ArrayList底层是由数组实现的
- 动态增长,以满足应用程序的需求
- 在列表尾部插入或删除非常有效
- 更适合查找和更新元素
- ArrayList中的元素可以为null
Set
- Set是元素无序并且不可以重复的集合,被称之为集
HashSet
- HashSet是set的一个重要实现类,称为哈希集
- HashSet中的元素无序并且不可以重复
- HashSet中只允许一个null元素
- 具有良好的存取和查找性能
Iterator
- Iteratro接口可以以统一的方式对各种集合元素进行遍历
- hasNext()方法检测集合是否有下一个元素
- next()方法返回集合中的下一个元素
map
- Map中的数据是以键值对(key-value)的形式存储的
- key-value以Entry类型的对象实例存在
- 可以通过key值快速地查找value
- 一个映射不能包含重复的键
- 每个键最多只能映射到一个值
HashMap
- 基于哈希表的Map接口的实现
- 允许使用null值和null键
- key值不允许重复
- HashMap中的Entry对象是无序排列的
LinkedList
概述
- 与ArrayList一样,LinkedList也按照索引位置排序,但它的元素之间是双向链接的
- 适合快速地插入和删除操作
- LinkedList实现List和Queue两个接口
构造方法
方法名 | 说明 |
---|---|
LinkedList() | 构造一个空列表 |
linkedList(Collection<? extends E> c) | 构造一个包含指定collection中的元素的列表,这些元素按其collection的迭代器返回的顺序排列 |
常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 将指定元素添加到此列表的结尾 |
void add(int index,E element) | 在此列表中指定的位置插入指定元素 |
boolean addAll(Collection <? extends E>c) | 添加指定collection中的所有元素到此列表的结尾 |
boolean addAll(int index,Collection<? extends E> c) | 将指定collection中的所有元素从指定位置开始插入此列表 |
void addFirst(E e) | 将指定元素插入此列表的开头 |
void addlast(E e) | 将指定元素添加到此列表的结尾 |
void clear() | 从此列表中移除所有元素 |
boolean contains(Object o) | 如果此列表包含指定元素,则返回true |
E get(int index) | 返回此列表中指定位置处的元素 |
E getFirst() | 返回此列表的第一个元素 |
E peekLast() | 获取但不移除此列表的最后一个元素;如果此列表为空则返回null |
E poll() | 获取并移除此列表的头(第一个元素) |
E pop() | 从此列表所表示的堆栈处弹出一个元素 |
void push(E e) | 将元素推入此列表所表示的堆栈 |
E remove() | 获取并移除此列表的头(第一个元素) |
E remove(int index) | 移除此列表中指定位置处的元素 |
Boolean remove(Object o) | 从此列表中移除首次出现的指定元素(如果存在) |
E removeFirst() | 移除并返回此列表的第一个元素 |
E set(int index,E element) | 将此列表中指定位置的元素替换为指定的元素 |
int size() | 返回此列表的元素数 |
Object[] toArray() | 返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组 |
4.5 集合排序
集合框架的体系结构[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-th4zNG1C-1662885657734)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220527091608930.png)]
Comparator接口
- 可以强行对某个对象进行整体排序的一个比较函数,有时候称它为比较器,位于java.util包下
- 可以将Comparator接口作为一个参数传递给Sort()方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xznCieRL-1662885657734)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220527092957890.png)]
对于自定义的对象,如果在集合中进行排序那么使用的是Collections.sort()在数组中进行排序使用的是Array.sort()
Comparator接口中包含两个方法:
方法名 | 作用 |
---|---|
int compare(T o1,T o2) | 比较用来排序的两个参数 |
boolean equals(object obj) | 指示其他对象是否等于此Comparator |
int compare(T o1,T o2) 其中 o1,o2就是要用来比较的两个对象
该方法的返回值及其代表的含义:
如果o1<o2,返回负整数。
如果o1>o2,返回正整数
如果o1==o2,返回0
- boolean equals(Object obj)方法,指定对象是否“等于”当前对象。Object类中有一个同样的方法,Object类是所有类的根类,comparator接口中的equals()方法可以被Object类中的equals()方法覆盖,所以在对Comparator接口进行实现的时候,可以重写equals()方法也可以不重写。因为Object类已经重写过了,但是compare()方法是一定要重写的。
接下来是一个案例 这个案例用来实现 对于自定义的类 Cat 我想要对它的对象们进行排序 排序的规则是我自己的定义的:按照名字进行排序 (实质上就是字符串排序)
1、首先我要有个Cat类、里面定义了一些最基本的属性
2、创建一个比较类去实现Comparator接口,在这个类中定义比较规则
3、创建一个测试类,里面创建几个Cat对象,把它们放进集合里,然后利用Colletions.sort(List1ist,Comparator<? super T>c)方法排序出来
【Cat类】
package com.jinglan.sort;
public class Cat {
private String name;//名字
private int age;//年龄
private String species;//品种
//构造方法
public Cat(String name, int age, String species) {
super();
this.name = name;
this.age = age;
this.species = species;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
@Override
public String toString() {
return " [名字=" + name + ", 年龄=" + age + ", 品种=" + species + "]";
}
}
【比较类】
package com.jinglan.sort;
import java.util.Comparator;
public class CatNameComparator implements Comparator<Cat> {//定义了一个CatNameComparator类实现Comparator接口对Cat进行比较
//重写compare()方法
public int compare(Cat o1,Cat o2) {//对o1、o2进行某种比较
//按名字升序排序 名字比较
String name1 = o1.getName();
String name2 = o2.getName();
int n = name1.compareTo(name2);//compareTo()对两个**字符串**!!!!进行比较,比较的结果就根据返回的int类型的变量值情况判断跟compare()的比较规则一样
return n;
//compare()方法的返回值是由compareTo()方法的返回值决定的,刚好两个方法的返回值意义是一样的,于是就实现了比较
}
}
【测试类】
package com.jinglan.sort;
//测试
import java.util.*;
public class CatNameComparatorTest {
public static void main(String[] args) {
//创建Cat对象
Cat huahua = new Cat("huahau",2,"英国短毛猫");
Cat fanfan = new Cat("fanfan",3,"中华田园猫");
Cat jianjian = new Cat("jianjian",3,"中华田园猫");
//将对象存到集合中
ArrayList<Cat> CatList = new ArrayList<Cat>();
CatList.add(huahua);
CatList.add(fanfan);
CatList.add(jianjian);
//排序
System.out.println("排序前:");
for(Cat cat:CatList) {
System.out.println(cat);
}
System.out.println();
System.out.println("排序后:");
Collections.sort(CatList, new CatNameComparator());//对CatList集合中的对象进行比较,比较的依据就是CatNameComparator类中定义的
for(Cat cat:CatList) {
System.out.println(cat);
}
}
}
Comparable接口
- 可以强行对每个实现它的对象进行整体排序,位于java.lang包下
- 这种排序被称为类的自然排序,compareTo()方法被称为它的自然比较方法。
- 可以将Comparab接口作为一个参数传递给sort()方法.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uJsUxLzf-1662885657735)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220527102432791.png)]
对于自定义的对象,如果在集合中进行排序那么使用的是Collections.sort()在数组中进行排序使用的是Arrays.sort()
Comparable接口中只包含一个方法:
方法名 | 作用 |
---|---|
int compareTo(T o) | 比较此对象与指定对象的顺序. |
该方法的比较规则:
观察返回值
该对象>指定对象,返回正整数。
该对象<指定对象,返回负整数。
该对象=指定对象,返回0
案例
package com.jinglan.sort;
import java.lang.Comparable;
public class Goods implements Comparable<Goods> {// 定义Goods类并实现Comparable接口
private String id;// 商品编号
private String name;// 商品名称
private double price;// 商品价格
// 构造方法
public Goods(String id, String name, double price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
// getter()、setter()方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
// toString()方法
@Override
public String toString() {
return " [商品编号=" + id + ", 商品名称=" + name + ", 商品价格=" + price + "]";
}
// 要实现Comparable接口就要实现它的抽象方法compareTo()
public int compareTo(Goods o) {// 传入参数指定对象
// 将当前对象的价格与指定对象的价格进行比较
double price1 = this.getPrice();
double price2 = o.getPrice();
// 升序
// price1-price2返回的是一个double值 comparaTo()返回的是int值
// 所以要将double值转换为int值 方法是生成一个double对象调用intValue()方法取出它的整数部分 并将它赋给变量n
int n = new Double(price1 - price2).intValue();
return n;
}
}
package com.jinglan.sort;
import java.util.*;
public class GoodsTest {
public static void main(String[] args) {
// 创建商品对象
Goods g1 = new Goods("s001", "手机", 2000);
Goods g2 = new Goods("s001", "电冰箱", 5000);
Goods g3 = new Goods("s001", "电视机", 3000);
// 创建集合 指定集合中的元素类型为Goods对象
ArrayList<Goods> list = new ArrayList<Goods>();
// 将商品对象添加到集合中去
list.add(g1);
list.add(g2);
list.add(g3);
// 排序前
System.out.println("排序前:");
for (Goods goods : list) {
System.out.println(goods);
}
// 排序后
System.out.println("排序后:");
Collections.sort(list);// 调用Comllections.sort()方法这个方法不需要传入比较器
for (Goods goods : list) {
System.out.println(goods);
}
}
}
- Comparator 和 Comparable的区别
Comparator | Comparable |
---|---|
位于java.util包 | 位于java.lang包 |
在要比较的类的外部实现该接口 | 在要比较的类上实现该接口 |
调用sort方法时,要指定Comparator的实现类 | 调用sort方法时,只需要指定集合名即可 |
4.6 泛型
泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用
- 什么是泛型
泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型的使用
-
List list=new ArrayList();
-
Java SE7及以后的版本中,构造方法中可以省略泛型类型。
List list=new ArrayList<>();
4.7 多线程
- 进程的概念
- 进程是指可执行程序并存放在计算机存储器,的一个指令序列,它是一个动态执行的过程
线程是比进程还要小的运行单位,一个进程包含多个线程,线程可以看成一个子程序
4.8 IO输入输出流
一.什么是IO
java中I/O操作主要是指使用Java进入输入,输出操作Java进行输入,输出操作,java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。
Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对快传输提供支持,在核心库 java.nio中采用的是便是块IO.
流IO的好处是简单易用,缺点是效率较低,块IO效率很高,但编程比较复杂。
Java IO模型:
Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能,例如,您需要1一个具有缓冲的文件输入流,则应当组合使用FIleInputStream和BufferedInputSteam.
二.数据流的基本概念
数据流是一串连续不断的数据的集合,就像水管里的水流,在水管的一端一点一点地供水,而在水管的另一端看到的是一股连续不断的水流。数据写入程序是一段,一段地向数据流管道中写入数据,这些数据段会按先后顺序形成一个长的数据流。对数据读取程序来说,看不到数据流在写入时的分段情况,每次可以读取其中的任意长度的数据,但只能先读取前面的数据后,再读取后面的数据。不管写入时是将数据分多次写入,还是作为一个整体一次写入,读取时的效果都是完全一样的。
“流是磁盘或其它外围设备中存储的数据的源点或终点。”
在电脑上的数据有三种存储方式,一种是外存,一种是内存,一种是缓存。比如电脑上的硬盘,磁盘,U盘等都是外存,在电脑上有内存条,缓存是在CPU里面的。外存的存储量最大,其次是内存,最后是缓存,但是外存的数据的读取最慢,其次是内存,缓存最快。这里总结从外存读取数据到内存以及将数据从内存写到外存中。对于内存和外存的理解,我们可以简单的理解为容器,即外存是一个容器,内存又是另外一个容器。那又怎样把放在外存这个容器内的数据读取到内存这个容器以及怎么把内存这个容器里的数据存到外存中呢?
在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:
标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中的称为输入流,将数据从内存写入外存中的称为输出流。
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。
三.java.IO层次体系结构
在整个Java.IO包中最重要的就是5个类和一个接口。5个类指的是File,OutputStream,InputSteeam,Writer,Reader一个接口是serializable,掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识。
Java I/O主要包括如下几个层次,包含三个部分:
- 流式部分——IO的主体部分;
- 非流式部分——主要包含一些辅助流式部分的类
- 其他类——文件读取部分的安全相关的类,如:serializablepermission类,以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类。
- 主要的类如下
- File(文件特征与管理):用于文件或目录的描述信息,例如生成新目录,修改文件名,删除文件,判断文件所在路径等。
- InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。
- OutputStream(二进制格式操作):抽象类。基于字节的输出操作,是所有输出流的父类
Java中字符是采用Unicode标准,一个字符是16位,即一个字符使用两个字节来表示。为此JAVA中引入了处理字符的流。
- Reader(文件格式操作):抽象类,基于字符的输入操作。
- Writer(文件格式操作):抽象类,基于字符的输出操作
- RandomAccessFile(随机文件操作):它的功能丰富,可以从文件任意位置进行存取(输入,输出操作)
Java中的IO流的体系结构如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2oWHcNC-1662885657735)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220607210819508.png)]
四.非流式文件夹—File类
在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。
File类共提供了三个不同的构造函数,以不同的参数形式灵活的接受文件和目录名信息。构造函数:
- File(String pathname) 例:File f1=new File(“FileTest1.txt”)//创建文件对象f1,f1所指的文件是在当前目录下创建的FileTest1.txt
- File(String parent,String child) 例:FIle f2=new File(“D:\\dir1”,“FileTest2.txt”)// 注意:D:\dir1目录事先必须存在,否则异常
- File(File parent,String child) File f4=new File(“\dir3”);File f5=new File(f4,“FileTest5.txt”); //在如果 \dir3目录不存在使用f4.mkdir()先创建一个对应于某磁盘文件或目录的File对象一经创建, 就可以通过调用它的方法来获得文件或目录
方法
方法名 | 作用 |
---|---|
boolean exists() | 判断文件或目录是否存在 |
boolean isFile() | 判断是文件还是目录 |
boolean isDirectory() | 判断是文件还是目录 |
String getName() | 返回文件名或目录名 |
String getPath() | 返回文件或目录的路径 |
long length() | 获取文件的长度 |
String[] list() | 将目录中所有文件名保存在字符串数组中返回 |
boolean renameTo(File newFile) | 重命名文件 |
void delete(); | 删除文件 |
boolean mkdir() | 创建目录 |
五. Java.IO流类库
1,io流的四个基本类
java.io中包含了流式I/O所需要的所有类。在java.io包中有四个基本类InputStream,OutputStream及Reader,Writer类,它们分别处理字节流和字符流
基本数据流的I/O
输入/输出 | 字节流 | 字符流 |
---|---|---|
输入流 | Inputstream | Reader |
输出流 | OutputStream | writer |
IO框架:
Java中其他多种多样的变化的流均是由它们派生出来的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyUMRTeU-1662885657735)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220609084432811.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1RWwSEI-1662885657736)(C:\Users\adiem\AppData\Roaming\Typora\typora-user-images\image-20220609084444385.png)]
六.字节流InputStream/OutputStream
一,按I/O类型来总体分类:
- Meonry 1)从/内存数组读据:CharArrytReader,ChararryWriter,
ByteArrayInputStream,ByteArrayOutputSteam2)从/向内存字符串读写数据StringReader,StringWriter,StringBufferInputStream
- Pine管道 实现管道的输入和输出(进程间通信):PipedReader,PipedWriter
- File文件流。对文件进行读,写操作:FileReader,FileWriter,FileInputSteam,FileOutputStream,FileOutputStream
- ObjectSerialization 对象输入,输出:ObjectctlInputSteam,ObjectOutPutStream
- DataConversion数据流 按基本数据类型读,写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
- Printing 包含方便的打印方法:printWriter,printStream
- Buffering缓冲 在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader,BufferedWriter,BufferedInputSteam,BufferedOutputSteam
- Filtering 滤流,在数据进行读或写时进行过滤:FilterReader,FilterWriter,FilterInputStream,FilterOutputStream过
- Concatenation合并输入 把多个输入流连接成一个输入流:sequenceInputStream
- Counting 计数 在读入数据时对行计数:LineNumberReader,LineNumberInputStream
- Peeking Ahead 通过缓存机制,进行预读:PushbackReader,PushbackInputStream
- Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter
isDirectory() | 判断是文件还是目录 |
| String getName() | 返回文件名或目录名 |
| String getPath() | 返回文件或目录的路径 |
| long length() | 获取文件的长度 |
| String[] list() | 将目录中所有文件名保存在字符串数组中返回 |
| boolean renameTo(File newFile) | 重命名文件 |
| void delete(); | 删除文件 |
| boolean mkdir() | 创建目录 |
五. Java.IO流类库
1,io流的四个基本类
java.io中包含了流式I/O所需要的所有类。在java.io包中有四个基本类InputStream,OutputStream及Reader,Writer类,它们分别处理字节流和字符流
基本数据流的I/O
输入/输出 | 字节流 | 字符流 |
---|---|---|
输入流 | Inputstream | Reader |
输出流 | OutputStream | writer |
IO框架:
Java中其他多种多样的变化的流均是由它们派生出来的
[外链图片转存中…(img-KyUMRTeU-1662885657735)]
[外链图片转存中…(img-l1RWwSEI-1662885657736)]
六.字节流InputStream/OutputStream
一,按I/O类型来总体分类:
- Meonry 1)从/内存数组读据:CharArrytReader,ChararryWriter,
ByteArrayInputStream,ByteArrayOutputSteam2)从/向内存字符串读写数据StringReader,StringWriter,StringBufferInputStream
- Pine管道 实现管道的输入和输出(进程间通信):PipedReader,PipedWriter
- File文件流。对文件进行读,写操作:FileReader,FileWriter,FileInputSteam,FileOutputStream,FileOutputStream
- ObjectSerialization 对象输入,输出:ObjectctlInputSteam,ObjectOutPutStream
- DataConversion数据流 按基本数据类型读,写(处理的数据是Java的基本类型(如布尔型,字节,整数和浮点数)):DataInputStream、DataOutputStream
- Printing 包含方便的打印方法:printWriter,printStream
- Buffering缓冲 在读入或写出时,对数据进行缓存,以减少I/O的次数:BufferedReader,BufferedWriter,BufferedInputSteam,BufferedOutputSteam
- Filtering 滤流,在数据进行读或写时进行过滤:FilterReader,FilterWriter,FilterInputStream,FilterOutputStream过
- Concatenation合并输入 把多个输入流连接成一个输入流:sequenceInputStream
- Counting 计数 在读入数据时对行计数:LineNumberReader,LineNumberInputStream
- Peeking Ahead 通过缓存机制,进行预读:PushbackReader,PushbackInputStream
- Converting between Bytes and Characters 按照一定的编码/解码标准将字节流转换为字符流,或进行反向转换(Stream到Reader,Writer的转换类):InputStreamReader、OutputStreamWriter