小白总结java
-!~
java基础知识
Scanner的使用
import java.util.Scanner;public class Dome6 { public static void main(String[] args) { //实例化一个对象 //System.in从九品上输入 Scanner scanner=new Scanner(System.in); System.out.println("请输入一个数"); int anInt= scanner.nextInt(); System.out.println("打印这个数="+anInt); }
如果我们使用的API不是位于java.lang包中,就需要使用import语句导包,导包的语法是import 包名.类名,由于类位于java.util.Scanner中;
Scanner使用的时候注意事项
注意类型的一致性。不一致容易导致数据的一致性的问题
IDEA插件的的安装和卸载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6A9AGrXQ-1654435923219)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220502151237716.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aTodhjCd-1654435923221)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220502151438841.png)]
Translation翻译插件的使用
翻译地址使用 https://dict.cn/translation
方式一
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jVJhS7yi-1654435923223)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220502153117441.png)]
快捷键 ctr +shift+y
方式2,翻译选中的内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vHyN5Npr-1654435923224)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220502153932059.png)]
javaAPI的使用
1:如何学习javaAPI的使用
学习java语言主要学习java 提供日常开发java项目中经常使用的API(类,接口,枚举,) 。我们之前使用非常多的java包
java.lang.System类
以后开发项目的时会用jar包
java API的使用
https://docs.oracle.com/javase/specs/jls/se8/html/index.html
javaAPI源码的使用
当我们在看文档的时不知道的时候,我们可以看一一下java的源码的设计,实现的的过程,可以提高自己的技术水平
ctr+F12我们可以查看方法
java 变量的交换
变量的交换
public class VariablemSwapTemp { public static void main(String[] args) { int left=10; int right=20; System.out.println("交换前:=left"+left+"right="+right); //java里面没有*和引用 int temp=left; left=right; right=temp; System.out.println("交换后:=left"+left+"right="+right); }}
public class VariablemSwap1 { public static void main(String[] args) { int left=10; int right=20; System.out.println("交换前:=left"+left+"right="+right); //java里面没有*和引用 left=left+right; right=left-right; left=left-right; System.out.println("交换后:=left"+left+"right="+right); }}
public class VariablemSwapTemp public static void main(String[] args) { int left=10; int right=20; System.out.println("交换前:=left"+left+"right="+right); //java里面没有*和引用 int temp=left; left=right; right=temp; System.out.println("交换后:=left"+left+"right="+right); }}
1.普通交换变量__需要增加内存空间
2.算术交换————数据会溢出,精度的得失
3.通过^运算 数据会溢出,精度的得失
public class VariablemSwapTemp2 { public static void main(String[] args) { int left=10; int right=20; System.out.println("交换前:=left"+left+"right="+right); //java里面没有*和引用 left=left^right; right=left^right; left=left^right; System.out.println("交换后:=left"+left+"right="+right); } }
数组的反转
public static void main(String[] args) { int []numbers={1,2,3,4,5,6}; System.out.println("数组反转之前"+ Arrays.toString(numbers)); int starIndex=0; int endIndex=numbers.length-1; int count=1; while (starIndex<endIndex){ numbers[starIndex]=numbers[starIndex]^numbers[endIndex]; numbers[endIndex]=numbers[starIndex]^numbers[endIndex]; numbers[starIndex]=numbers[starIndex]^numbers[endIndex]; System.out.println("第"+count+"次收尾交换后"+Arrays.toString(numbers)); count++; starIndex++; endIndex--; } }}
java方法的概述
方法的概述
程序由多个类组成,配置文件,类通过都是包含多个不同的功能,封装了特定的代码块,
方法的好处
1.提高了代码的复用性,提高开发效率
2,降低了程序的耦合性
方法的特点
方法不调用不会执行
方法要掌握哪些东西
1,方法的相关概念
2.方法的定义和使用
3.方法的调用内存机制
4,方法的基本案例
5,方法的可变参数,参数的个数可变
6,方法的重载,同一个类中,方法名相同,方法的参数不同
7,方法的参数传递机制
8方法的递归调用
方法的定义
方法分为有返回值和无返回值
修饰符 返回值类型 方法名(形参类型){方法体return ;}
1 .修饰符
2.返回值类型
3.方法名:给方法取的名字,标识符 ,应该遵守标识符的命名规则
4.形参列表
5.方法体,方法体就是方法需要完成需要的功能
6.return
return 结束方法
return返回值:表示结束方法将返回值赋值
7.void表示没有返回值
8.方法的注意事项
1方法不能定义在其他方法的内部
单独调用 一般用与没有返回值
public class Meth { public static void main(String[] args) { int a=10; int b=20; add(a,b); } / * * @param left 第一个操作数 * @param right 第2个操作数 * @return 返回两个数的和 */ public static int add(int left,int right){ return left+right; }}
输出调用,使用System.out.println()
public class Meth { public static void main(String[] args) { int a=10; int b=20; add(a,b); //输出调用 System.out.println(add(a,b)); //赋值调用 int result=add(a,b); System.out.println("赋值调用完成两个整数相加"+result); } / * * @param left 第一个操作数 * @param right 第2个操作数 * @return 返回两个数的和 */ public static int add(int left,int right){ return left+right; }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kVcvqkpz-1654435923229)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503105105560.png)]
方法的可变参数和重载机制
方法的可变参数
1方法的可变参数的个数是可变的
可变参数的方法定义
修饰符 返回值类型 方法名(参数类型。。。参数名){
方法体
}
和下面的格式是等价的
修饰符 返回值类型 方法名 (参数类型[] 参数名){
方法体
}
可变参数的底层维护了一个数组
数组元素类型必须相同,可变参数的数据类型必须相同
可变参数作为形参列表的最后一个了参数,方法只能有一个可变参数
package Text;public class PrintUtuisTest { public static void main(String[] args) { String[]books={"onjava8","java核心技术","java编程逻辑"}; PrintUtils.printContent(books); PrintUtils.printContent("java核心技术","java编程思想"); }}
package Text;public class PrintUtils { public static void printContent(String...contents){ for (int i = 0; i < contents.length; i++) { System.out.println(contents[i]); } }}
方法重载机制
方法的重载指的是在同一个类中或者是子父类的继承关系中,方法名相同,方法的参数不同,方法参数不同指的是
1.方法参数个数不同
2.方法参数的数据类型不同
3.方法参数数据类型的顺序不同
package Text;public class Method { public static boolean compare(int left ,int right){ System.out.println("compare(int ,int)"); return left==right; } public static boolean compare(long left ,long right){ System.out.println("compare(long ,long)"); return left==right; } public static boolean compare(boolean left ,boolean right) { System.out.println("compare(boolean ,boolean)"); return left == right; }}
package Text;public class MethodTest { public static void main(String[] args) { Method.compare(1000L,1000L); }}
方法的参数传递机制
形参和实参
形参 方法定义的参数
实参 调用是的参数
形参的改变不会影响实参
package method;public class MethodArgsPassTest { public static void main(String[] args) { int number=10; MethodArgsPass.changse(number); System.out.println("1.实参 number="+number); MethodArgsPass.changse(number); System.out.println("1.实参 number="+number); }}
package method;public class MethodArgsPass { public static void changse(int number){System.out.println("1.形参 number="+number);number =100;System.out.println("1.形参 number="+number); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pqJXzV7A-1654435923230)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503190432318.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lLprm2Sy-1654435923230)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503191830271.png)]
2.引用数据类型的参数传递机制
引用数据类型作为参数传递的时传递内存地址
特点:形参内存地址的改变 不会影响实参的内存地址
特点2:形参的内存地址不变,但是改变内存地址指向的内容后,实参的内存地址的指向不会改变,实参的内存地址指向的内容也后改变
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-devyzvit-1654435923231)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503194231319.png)]`
package method;import java.util.Arrays;public class MethodArgsPass { public static void changse(int number){System.out.println("1.形参 number="+number);number =100;System.out.println("1.形参 number="+number); } public static void change (int [] numer){ System.out.println("1.形参 nuner的内存地址"+numer); numer=new int []{100,200,300}; System.out.println("1.形参 numer的内存地址"+numer); } public static void chang(char[] chars){ System.out.println("1.形参 chars数组的内容"+ Arrays.toString(chars)); chars[0]='z'; System.out.println("1.形参 chars数组的内容"+ Arrays.toString(chars)); }}
package method;import java.util.Arrays;public class MethodArgsPassTest { public static void main(String[] args) { int number=10; MethodArgsPass.changse(number); System.out.println("1.实参 number="+number); MethodArgsPass.changse(number); System.out.println("1.实参 number="+number); / * 引用数据类型参数传递机制 */ int[] numer={1,2,3}; System.out.println("1.实参 nuner的内存地址"+numer); MethodArgsPass.change(numer); System.out.println("1.实参 nuner的内存地址"+numer); char []chars={'a','b','c'}; System.out.println("1.实参 chars数组的内容"+ Arrays.toString(chars)); MethodArgsPass.chang(chars); System.out.println("1.实参 chars数组的内容"+ Arrays.toString(chars)); System.out.println("1.实参 chars数组的内容"+ Arrays.toString(chars)); }}
java 面向对象和面向过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBVQQwMf-1654435923232)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503210140019.png)]
.面向过程
面向过程对象关注的是的是过程,必须要清楚每一个步骤,然后一一的实现,问题比较简单的时可以用
。面向对象
面向对象关注的是对象,通过调用对象的行为,不需要清楚每一个步骤,解决复杂问题是可以使用面向对象实现
类和对象关系
什么是类?
生活中的类:人类,鸟类,图书馆类
类的特点:抽象,也就是客观世界不存在的
类指的是有相同属性和行为的一类事物
属性:静态属性
行为:动态特征
什么是对象
对象的实例化,对象是具体的,
类和对象关系
1类做成对象的数据类型
2.对象是根据类来创建的
3类中有什么属性和行为,对象就有什么属性和行为
4。类是抽象的,成员变量没有具体值,成员方法不能直接使用,对象是具体的,对象的成员变量的具体值,对象的成员方法可以直接使用
类和对象的使用
类的定义
类定义的步骤
1.定义类
类定义的格式
修饰符 class 类名{
//定义成员变量
数据类型 变量名
//定义成员方法
public 返回值类型 方法名(写参类型 形参名)
//方法体
}
2.定义成员方法
3.定义成员变量
对象的创建和使用
创建对象的格式 类名 对象名=new 类名();
对象的使用
1.对象名.成员方法
2.对象名.方法名
package Test.oop;import jdk.nashorn.internal.parser.Scanner;public class CellphoneTest { public static void main(String[] args) { Cellphone xm12=new Cellphone(); System.out.println("xm12的型号"+ xm12.model); xm12.model="xm12"; xm12.price=699; xm12.color="红色"; System.out.println("xm12的价格是"+xm12.price+"xm12型号"+xm12.model+"xm12颜色"+xm12.color); long number=18187876931l; xm12.call(number); xm12.sendMessage(number,"您好"); }}
package Test.oop;public class Cellphone { /* 成员变量/ / * 手机型号 */ String model; / * 手机品牌 */ String brand; / * 价格 */ Integer price; String color; public void call(long number){System.out.println("正在给"+number+"打电话"); } public void sendMessage(long number,String message){System.out.println("正在给"+number+"发短信,短信内容"+message); }}``## java成员变量和局部变量1.成员变量和局部变量的定义的位置不同。成员变量定义在类中,方法外。局部变量定义在方法内。成员变量初始化机制不同,致与赋什么值,由成员变量的数据类型。局部变量初始化由开发人员手动赋值```javapackage Test.oop;public class Initialize { public static void main(String[] args) { Data data=new Data(); System.out.println("long类型的默认值"+data.lng); System.out.println("数组类型的默认值"+data.array); System.out.println("char类型的默认值"+data.ch); //u0000不可见字符 System.out.println("boolean类型的默认值"+data.bl); System.out.println("double类型的默认值"+data.dbl); }}class Data{ long lng; double dbl; char ch; boolean bl; int [] array; Data reference;}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zeN40ASl-1654435923238)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220503234613377.png)]
3.成员变量和局部变量的生命周期不同
。成员变量是从属于对象,当对象创建的时候,会开瓶内存空间储存变量的数据,当对象被销毁
。局部变量是从属于方法,当局部变量位于栈区,当方法执行完成,局部变量随之销毁
深入理解构造器
构造器就是构造方法,构造方法是一个特的方法
。构造方法的方法名就是类名
。构造方法没有返回值,连void的方法都不需要
。构造方法的调用是通过new关键字来实现。实例化对象,在调用对象的时候自动调用
没有设置构造方法。系统会自动生成一个构造方法,在源码中会有一个构造器
构造方法的作用
1.创建对象,完成对象的初始化,通过无参的构造器给对象的成员变量赋初始值
2.通过有参数的构造方法给对象的成员变量赋值
构造方法的定义和使用
构造方法可以重载
无参构造方法的定义
public 类名(){ }
有参构造器的定义
public 类名(参数类型 参数名){ }
构造方法的使用
1.无参数构造器的使用
Cellphone Cellphone=new Cellphone();
2.有参数构造方法的使用
//有参数构造器的使用 Cellphone cellphone=new Cellphone("小米12"); System.out.println("Cellphone对象的属性"+cellphone.model);
package Test.oop;public class Cellphone { /* 成员变量/ / * 手机型号 */ String model; / * 手机品牌 */ String brand; / * 价格 */ Integer price; String color; public void call(long number){System.out.println("正在给"+number+"打电话"); } public void sendMessage(long number,String message){System.out.println("正在给"+number+"发短信,短信内容"+message); } public Cellphone(){ } public Cellphone(String model){this.model=model; }}
//全参构造器 public Cellphone(String model,String brand,Integer price,String color){this.model=model;this.brand=brand;this.price=price;color=color; }
构造器的注意事项
1.如果一个类没有定义构造器,系统会自动生成一个构造方法
2.如果一个类定义了构造器,那么系统不会在提供无参构造器,如果删除了无参数构造器,我们手动设置
java面向对象封装
封装概述
生活中中封装的例子:一个接口
面向对象编程语言是对客观世界模拟,将类的成员隐藏在类的内部,外部的程序无法直接访问
封装的规则:将类的成员隐藏在类的内部,外部程序无法访问,只能通过类提供的公共方法去访问隐藏类的成员
private关键字的使用
private是一个访问修饰符
四个访问修饰符,按照权限从小到大的顺序排序 :private<default<protected<public
private通常都是用与修饰成员变量和成员方法:private修饰的成员只能在当前类中访问
package Test.oop;public class PrivateTest { public static void main(String[] args) { Cellphone xm12 =new Cellphone(); System.out.println("手机的默认重"+xm12.getWeight()); xm12.showCellphoneInfo(); }}
package Test.oop;public class Cellphone { /* 成员变量/ / * 手机型号 */ String model; / * 手机品牌 */ String brand; / * 价格 */ Integer price; String color; public Integer getWeight() { return weight; } public void setWeight(Integer weight) { this.weight = weight; }public void showCellphoneInfo(){ System.out.println("手机重量"+weight);} private Integer weight; public void call(long number){System.out.println("正在给"+number+"打电话"); } public void sendMessage(long number,String message){System.out.println("正在给"+number+"发短信,短信内容"+message); } public Cellphone(){ } public Cellphone(String model){this.model=model; } //全参构造器 public Cellphone(String model,String brand,Integer price,String color){this.model=model;this.brand=brand;this.price=price;color=color; }}
3.属性的封装
封装的步骤
1.私有化属性(成员变量)
2.提供公共的get和set的方法
package Qaas;public class Cellphone1 { private String model; private String brand; private Integer price; private String color; public String getModel() { return model; } public void setModel(String model) { this.model = model; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Integer getPrice() { return price; } public void setPrice(Integer price) { if (price<0){ this.price=-1; return; } this.price = price; } public String getColor() { return color; } public void setColor(String color) { this.color = color; }}
public class Cellphone1TEXT { public static void main(String[] args) { Cellphone1 xm13 = new Cellphone1(); xm13.setBrand("xm13 max"); System.out.println("手机的型号" + xm13.getBrand()); xm13.setModel("华为"); System.out.println("手机型号" + xm13.getModel()); xm13.setPrice(-9999); System.out.println("手机的价格" + xm13.getPrice()); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONd03sDG-1654435923240)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220504144909167.png)]
this 关键字的使用
1.this关键字的概述
this关键字的本质:创建·好的·的·内存地址,当构造器调用之前,对象已经创建因此在构造方法中可以使用this表示当前对象
public Cellphone(){System.out.println("Cellphone()无参构造器"+this); }
package Test.oop;import jdk.nashorn.internal.parser.Scanner;public class CellphoneTest { public static void main(String[] args) { Cellphone xm12=new Cellphone(); System.out.println("Cellphone对象的地址"+xm12); Cellphone xm13=new Cellphone(); System.out.println("Cellphone对象的地址"+xm13); }}
this 关键字的使用
没有this关键字会有什么问题
1方法的形参名不能更够表明的意思
2,方法的形参和成员变量重名。导致赋值失败,变量在使用的时候遵守的接将近规则,
this关键字的应用场景
。成员变量私有化后,公共的get/set方法,set方法可以使用this关键字
。构造方法可以使用this关键字实现构造方法的调用
3.this关键字的注意事项
this关键字在调用构造方法时,必须在代码的第一行
2.this关键字不能在static方法中使用
3.this关键字不能在static成员(静态方法,静态初始化),中使用
java包机制
package和java开发常用的包
什么是包以及包的作用
1包就是文件箱存放不同用途的类和接口
package关键字
package关键字用于定义一个包,包的定义格式 package+包名
package Test.oop;
.包名就是公司的域名加上项目名和模块名
。包定义语句必须放在源文件的第一行
java开发常用的包
。java.lang java语言的核心包
。java.util 集合框架
2.import,static import
import
import是用于导入指定的包,java.lang不需要import导入,导入的格式就是import包名+类名
import java.util.Scanner;
在一个类中如果要使用两个重名的类
第一个类可以使用import导入指定包下的类
第2个类必须使用包名+类名来使用这个类(全限定名)
static import
static import静态导入是JDK1.5以后新增的特性
静态导入就是导入类的静态成员(静态属性,静态方法)
可以使用*表示导入当前包下的所有包
面向对象之继承
1.继承的概述
生话中的继承,1继承2(的所有的东西)
继承是面向对象的3大特征之一
java的继承就是一个(A类继承另一个类(B类),被继承的类叫做父类,继承其他的类(A类叫做子类
子类就可以获得父类的成员(成员变量 ,成员方法),子类不需要在定义继承得到成员变量和成员变量,通过继承提高了代码的可用性,多态的三个前提条件
java语言中通过extends关键字来实现类的继承
2.继承的使用
继承使用无非就是使用分类的成员
。子类的成员变量无法使用父类的私有成员变量,成员变量和成员方法,子类无法使用分类的构造方法
子类无法使用父类的
。类的成员方法
。类的构造方法
java只支持单继承
2.java类支持多层继承
9.方法的重写
1.方法的概述
方法的重载(overloading):在同一个类中,方法的参数不同(参数个数不同,参数的数据类型不同,参数数据类型的顺序不同)
方法的重写(Override)在父子类中,出现了一模一样的方法(父类和子类的方法 返回值,方法名,参数列表都一样)
方法的重写的使用
1.父类的方法完全不能满足业务需求,子类需要重写父类的方法
2.父类的方法完全满足业务需求,子类需要父类的方法
3.方法重写的注意事项
1.方法的重写必须是父子类继承关系,都是子类重写父类的方法
2.方法的重写要求父类和子类中的方法,返回值类型,方法名,参数列表都一样
3.方法重写时子类的方法访问权限必须大于或等于父类方法的访问权限
4.object类的介绍
java.lang.Obhect类是使用所有java类的父类
1.如果定义了一个类,那么这个类自动继承java.lang.Object
2.如果你定义了一个类,这个类继承了其他的父类,那么其他的·父类也会自动继承java.lang.object
子类继承父类之就可以拥有父类的非私有的成员(成员变量 ,成员方法)
obejct类有的非私有的成员方法,所有java子类都有
object类的方法的使用
通过API [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0TSBbxHm-1654435923241)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220504213215295.png)]
6.toString()方法的使用
toString()方法默认值返回字符串的表现形式,也就是包名+类名+@十六进制的哈希值
@Override public String toString() { return "Cellphone1{" + "model='" + model + '\'' + ", brand='" + brand + '\'' + ", price=" + price + ", color='" + color + '\'' + '}'; }
在开发当中,如果自定义的类,指类通常都是用于封装属性的信息,都会重写toString()的方法,用于返回对象的属性的信息。toString()方法的实现
7.equals()方法的使用
equals()方法默认比较的是对象的地址是否相等,在开发场景中,equals()方法通常都是去比较对象的内容(属性)是是否相等,因此都会去重写equals()方法
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Cellphone1 that = (Cellphone1) o; return Objects.equals(model, that.model) && Objects.equals(brand, that.brand) && Objects.equals(price, that.price) && Objects.equals(color, that.color); } @Override public int hashCode() { return Objects.hash(model, brand, price, color); }
4.native方法的介绍
本地方法
native方法的特点:
1没有方法方法体,只有方法签名
public int hashCode(
super关键字的作用
1.super关键字的·概述
this关键字表示当前对象
super关键字表示父类对象
2.super关键字的使用
super关键字在JAVA项目中的使用
1.super关键字访问父类的构造方法,使用方式是super(实参列表)
2.super关键字访问父类的非私有(成员变量,成员方法),使用方式super.构造方法名(实参列表)
this和super在JDK中的使用
1.this在String类中的使用
public String(String original) { this.value = original.value; this.hash = original.hash; }
public String() { this.value = "".value; }
2.super在java.io.BufferedlnpuStream类中的使用
public BufferedOutputStream(OutputStream out, int size) { super(out); if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } buf = new byte[size]; }
public FilterOutputStream(OutputStream out) { this.out = out; }
e
3.super关键字的注意事项
1.super关键字在调用父类构造方法是,必须作为构造方法的第一条语句
2.super关键字调用父类的非私有成员时,首先查找当前父类的非私有成员(成员方法),如果找到类就直接使用,如果没有找到,那就继续在祖宗类中查找,如果找到了就是用,如果没有找到就报错
javaBean
javaBean就是编写类的规范
1自定义类pojo
1.私有成员变量,提供公共的get和set方法
2.空参构造方法,全参构造方法
3.重写equals()和toString.hashCode()
2.接口
CellphoneService
CellphoneServicelml
访问权限修饰符
1.访问权限修饰符的概述
生话中的例子:校长办公室,经理办公室,董事长办公室
java的权限:通过访问权限修饰符来控制外界的访问类,类的成员(成员变量 成员方法 构造方法)访问权限
java提供3种访问权限修饰符
private 本类访问权限
protected 继承访问权限
.public 项目访问权限
java一共提供4的访问权限,除以上3的方法外,默认的是包的访问权限,没有对的关键字
2. 访问权限修饰符的使用
访问权限按照从小到大的排序
private<defaault<protected<public
public修饰符
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
private修饰的构造方法
private修饰构造方法的目的不让使用new关键字的使用来创建
单例模式 第一步就是私有化构造方法
private System() { }
private Runtime() {}
private修饰成员方法
如果在实现业务功能时,该业务功能只会被当前类的其他访问,那么强烈建议使用private关键字修饰,这样提供更好的封装性
会避免一些问题
public class CommonUserService { public void login(){ System.out.println("欢迎登录淘宝网络"); } private void statistics(){ System.out.println("统计当前登录用户的登录信息,IP.地址,次数,pc/App"); }}
2.访问权限
java默认就是包访问权限,该权限没有对应的·访问权限修饰符的关键字,相同可以删除
package Test.oop.permission.service;public class CommonUserService { void login(){ System.out.println("欢迎登录淘宝网络"); } private void statistics(){ System.out.println("统计当前登录用户的登录信息,IP.地址,次数,pc/App"); }}
package Text.permission.service;public class AccessPermissiionTest { public static void main(String[] args) { CommonUserService commonUserService=new CommonUserService(); commonUserService.login(); }}
3.继承访问权限
继承访问权限使用protected访问权限修饰符
继承访问权限在包访问权限的基础增加了不同包的访问权限
当你的方法想被不同包访问子类访问时建议使用protected如果方法重写的话,public也是可以的,因为子来方法的访问权限
package Test.oop.permission.service;public class CommonUserService { public void login(){ System.out.println("欢迎登录淘宝网络"); } private void statistics(){ System.out.println("统计当前登录用户的登录信息,IP.地址,次数,pc/App"); } protected void register(){ System.out.println("欢迎淘宝网"); }}
package Text.permission.servicepublic class AccessPermissiionTest { public static void main(String[] args) { CommonUserService commonUserService=new CommonUserService(); commonUserService.login(); }}
4项目访问权限
项目访问权限解除了包限制
public没有包限制 任何一个包都可以用
抽象类的概述
抽象类指的是使用abstract关键字修饰的类
抽象类和普通来不同的地方
1.抽象类不能实例化,也就是不能使用new关键字创建对象,它的作用就是作为父类,被子类来继承
2.抽象类包含(不是必须)抽象方法,抽象方法必须定义在抽象类类中
抽象类的成员
。成员变量
。成员方法
。构造方法
。抽象方法
子类继承抽象类以后
1.如果子类是普通类,那么需要重写父类的抽象方法
2.如果子类也是抽象类,不需要重写父类的抽象方法
抽象方法
抽象方法必须定义在抽象类中,抽象类没有它的方法体,其他跟普通方法一样(抽象方法也可以重载) 使用abstract关键字修饰,它的作用就是被子类重写
2.抽象类使用
1.抽象类的定义格式
public abstravt class className
public abstract class Animal { }
2.抽象方法的定义格式
package Test.oop.abstracts;public abstract class Animal { / * 动物吃东西 */ public abstract void eat();}
访问权限修饰符 abstract 返回值类型 方法名(形参列表);
package Test.oop.abstracts;public class Cat extends Animal{ @Override public void eat() { System.out.println("吃大"); }}
package Test.oop.abstracts;public class Panda extends Animal{ @Override public void eat() { System.out.println("吃东西"); }}
package Test.oop.abstracts;public class AbstractClassTest { public static void main(String[] args) { Cat cat=new Cat(); cat.eat(); Panda panda=new Panda(); panda.eat(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pCXHe1jb-1654435923242)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220507163547235.png)]
package Test.oop.abstracts;public abstract class Animal { / * 动物吃东西 */ public abstract void eat(); public String getNationality() { return nationality; } public void setNationality(String nationality) { this.nationality = nationality; } public Animal() { } public Animal(String nationality) { this.nationality = nationality; } private String nationality; public abstract void sleep(String nationality);}
package Test.oop.abstracts;public class Cat extends Animal{ @Override public void eat() { System.out.println("吃大"); } @Override public void sleep(String nationality) { System.out.println( nationality+"小猫在睡觉"); }}
package Test.oop.abstracts;public class AbstractClassTest { public static void main(String[] args) { Cat cat=new Cat(); cat.eat(); Panda panda=new Panda(); panda.eat(); Panda china =new Panda("中国"); china.sleep(china.getNationality()); }}
package Test.oop.abstracts;public class Panda extends Animal{ public Panda(){ } public Panda(String nationality){ super(nationality); } @Override public void eat() { System.out.println("吃东西"); } @Override public void sleep(String nationality) { System.out.println("熊猫正在睡觉"); }}
3.模板方法模式的实现
抽象类最重要的思想是模板思想
网上买东西
1注册+实名认证
2.登录
3。搜索视频·
4添加到购物车
5.支付
6.提交订单
模式:解决某一类问题的固定套路
模板方法模式,
final关键字的使用
final关键字修饰类
final关键字用于修饰,变量 方法,其作用就表示不可变
final修饰的类不能改变,final在jdk.String.Loing
final关键字修饰变量
final关键字修饰的基本数据类型的变量,改变量就成了常量,常量是一但初始化以后就不能被修改,常量通常都是大写字母,多个单词使用下划线隔开,
final int DEFAUL_VALUE=10;
final关键字修饰引用数据类型的变量,改变量的对象的地址不能改变,但是对象的属性值还是可以改变的
package Test.oop;public class FinalTest { public static void main(String[] args) { final int DEFAUL_VALUE=10;final Order order=new Order("tb101"); System.out.println("订单号"+ order.getOrderId()); order.setOrderId("1002"); System.out.println("订单号"+order.getOrderId()); }}class Order{ private String orderId; public Order() { } public Order(String orderId) { this.orderId = orderId; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fC2c6GGG-1654435923242)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220507200600221.png)]
3.自定义不可变类
不可变类指的是类对象创建完成以后,就不允许修改对象的属性信息
1.将成员变量设置成private final
2.在构造方法中初始化final修饰的成员变量
3。在创建对象是调用对应的构造方法给成员赋值
package Test.oop;public class FinalTest { public static void main(String[] args) { final int DEFAUL_VALUE=10;final Order order=new Order("tb101"); System.out.println("订单号"+ order.getOrderId()); }}class Order{ private final String orderId; public Order() {this.orderId="tb1003"; } public Order(String orderId) { this.orderId = orderId; } public String getOrderId() { return orderId; }}
static关键字的使用
static关键字修饰变量
static关键字可以修饰变量,方法,代码,static关键字是静态的
static关键字修饰的变量就是静态变量,也叫类变量,从属于类,该来的所有对象都会共享同一份数据
package Test.oop;public class StaticTest { public static void main(String[] args) { RegisterInfo android =new RegisterInfo(); android.setUserName("zxs"); android.setSource("app"); System.out.println(android); RegisterInfo iOS=new RegisterInfo(); iOS.setUserName("lbm");// iOS.setSource("AOP"); System.out.println(iOS); }}class RegisterInfo{ / * 默认用户 */ private String userName; / * 默认注册来源 */ private static String source; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getSource() { return source; }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K9eu1FNR-1654435923243)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220507212100668.png)]
静态成员的内存机制
static关键字修饰方法
static关键字修饰的方法就是静态方法,也叫类方法,从属于类,类方法的直接调用通过类名。方法名(实参列表)调用可以
static 关键字作用注意事项
1.静态方法中不能出现this关键字,非静态方法可以使用this关键字
2.静态方法不能访问非静态的成员(非静态的成员成员 ,方法),静态方法可以访问访问静态成员,非静态成员可以访问一切成员
3.子类中出现了和父类一模一样的静态·方法,本质不是方法重写
static 静态代码块
static { }
你的代码只需要执行一次的时候使用静态代码块,例如注册驱动
static { System.out.println("我是一个静态代码块"); }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kh2l0UVt-1654435923244)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220507214830806.png)]
静态代码块在类加载就会执行,优先构造方法,只执行执行一次
如果你的测试类中有一个静态代码块,那么会优先main方法执行
package Test.oop;public class StaticTest { public static void main(String[] args) { RegisterInfo android =new RegisterInfo(); android.setUserName("zxs"); android.setSource("app"); System.out.println(android); RegisterInfo iOS=new RegisterInfo(); iOS.setUserName("lbm");// iOS.setSource("AOP"); System.out.println(iOS); }}class RegisterInfo{ / * 默认用户 */ static { System.out.println("我是一个静态代码块"); } private String userName; / * 默认注册来源 */ private static String source; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getSource() { return source; } public void setSource(String source) { this.source = source; } @Override public String toString() { return "RegisterInfo{" + "用户'" + userName + '\'' + ", 默认的注册来源:'" + source + '\'' + '}'; }}
5.static关键字在项目中的实践
static关键字在项目开发的时候通常都是用与封装工具方法,这些工具方法可以被项目的个模块使用的
初始化代码
1.初始化静态代码块
静态代码块是使用static修饰静态代码块,静态代码块随着类的首次加载就会执行,只执行一次,例如数据库链接注册驱动
public class CodeBlokTest { public static void main(String[] args) { House house=new House(); System.out.println( "window1"); }}class House{ static Window window1; // static { System.out.println("在静态代码块中初始化第一块窗"); Window =new Window(" window1"); }}class Window{ private String name; public Window() { } public Window(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "房屋的客户信息{" + "客户的信息'" + name + '\'' + '}'; }}
2.初始化构造代码块
构造代码块是没有使用static修饰的代码块,主要用于统计对象创建的·个数
public class CodeBlokTest { public static void main(String[] args) { House house=new House(); System.out.println("当前房屋的窗的数量"+Window.getWindowCount()); }}class House{ static Window window1; // static { System.out.println("在静态代码块中初始化第一块窗"); Window window =new Window(" window1"); }}class Window{ private static int WindowCount=0; private String name; public Window() { } public Window(String name) { this.name = name; } / * 构造代码块 */ {WindowCount++; } public static int getWindowCount() { return WindowCount; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "房屋的客户信息{" + "客户的信息'" + name + '\'' + '}'; }}
package Test.oop;public class CodeBlokTest { public static void main(String[] args) { House house=new House(); System.out.println("当前房屋的窗的数量"+Window.getWindowCount()); }}class House{ static Window window1; Window window2; // static { System.out.println("在静态代码块中初始化第一块窗"); Window window =new Window(" window1"); } / * 构造代码块 */ { System.out.println("2.在静态代码块中初始化第一块窗户"); }}class Window{ private static int WindowCount=0; private String name; public Window() { } public Window(String name) { this.name = name; } / * 构造代码块 */ {WindowCount++; } public static int getWindowCount() { return WindowCount; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "房屋的客户信息{" + "客户的信息'" + name + '\'' + '}'; }}
package Test.oop;public class CodeBlokTest { public static void main(String[] args) { Window window3 =new Window("window3"); House house=new House( window3); System.out.println("当前房屋的窗的数量"+Window.getWindowCount()); }}class House{ static Window window1; Window window2; final Window window3; // static { System.out.println("在静态代码块中初始化第一块窗"); Window window =new Window(" window1"); } / * 构造代码块 */ { System.out.println("2.在静态代码块中初始化第一块窗户"); } public House(Window window3){ System.out.println("在3;在构造方法窗3"); this.window3=window3; System.out.println(window3); } public House(){ window3=null; }}class Window{ private static int WindowCount=0; private String name; public Window() { } public Window(String name) { this.name = name; } / * 构造代码块 */ {WindowCount++; } public static int getWindowCount() { return WindowCount; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "房屋的客户信息{" + "客户的信息'" + name + '\'' + '}'; }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uHvpnJl9-1654435923246)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220508145844970.png)]
静态代码块.构造代码块,构造方法的执行的顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-75xuGWTA-1654435923247)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220508150453211.png)]
静态的的码块>构造代码块>构造方法
3.初始化局部代码块
局部代码块指的是在方法的内部的的代码块
局部代码块方法执行可以执行 ,因为局部代码块的变量作用作用域是最小的,当局部代码块执行完成后,局部变量的内存空间就会释放,因此局部代码块空间节省了空间
public class CodeBlokTest { static void localCodelock(){ int number=10; { int value=20; System.out.println("valve=" + value); } System.out.println("number=" + number); } public static void main(String[] args) { Window window3 =new Window("window3"); House house=new House( window3); System.out.println("当前房屋的窗的数量"+Window.getWindowCount()); localCodelock(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0eU9TpYU-1654435923247)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220508152024468.png)]
java接口
接口是一种设计思想:规范和实现分离
2.接口的定义
类使用class定义
接口interface定义
public interface InterfaceName{}
接口的成员
接口主要是用来定义方法的,不同的JDK版本支持的方法不相同的
。java7和之前的版本支持常量和抽象方法
。java8的接口增加了默认方法和静态方法
。java9增加了私有方法(私有方法和静态方法)
接口的常量和抽象方法的定义
1.接口中定义常量
接口中的常量默认是public static final
/ * 网站名称 * 常量 */public static final String WEB_SITE_NAME="淘宝网" ; public abstract void login(); / * 重置密码 * */
抽象方法的定义
接口抽象方法默认是public abstract
接口中的抽象方法的实现类的重写(必须重写)
默认方法和静态方法的定义
1.默认方法的定义
默认方法的方法访问权限,默认是public
/ * 重置密码 * */ public default void resetPassword(){ System.out.println("请输入手机号并点击发放验证码"); System.out.println("请输入收到的手机验证码"); System.out.println("请输入新密码"); System.out.println("请确认新密码"); System.out.println("你的密码重置成功"); }
2.静态方法
/ * 统计网站的注册信息 */ static void staisftics(){ }
私有成员方法和静态方法的定义
私有方法成员方法·外界无法调用,私有成员方法通常都是给默认方法调用的
外界通过调用默认方法来间接调用私有成员方法
私有方法
/ * 发送验证码 * 私有成员方法 * */ private void sendCode(){ System.out.println("您好,验证码xxxxxxx,请不要告诉别人"); }
2.私有静态方法的定义
/ * 从数据库中的方法 * 私有静态方法 * @return */ static long getAllUserInfo(){ System.out.println("从数据库中查寻数据"); int count=1_000_000_000; return count; }
public interface UserService { / * 网站名称 * 常量 */ String WEB_SITE_NAME="淘宝网" ; / * 登录 * 抽象方法 */ public abstract void login(); / * 重置密码 * */ public default void resetPassword(){ System.out.println("请输入手机号并点击发放验证码"); System.out.println("请输入收到的手机验证码"); System.out.println("请输入新密码"); System.out.println("请确认新密码"); System.out.println("你的密码重置成功"); } / * 发送验证码 * 私有成员方法 * */ / * 从数据库中的方法 * 私有静态方法 * @return */ static long getAllUserInfo(){ System.out.println("从数据库中查寻数据"); int count=1_000_000_000; return count; } / * 统计网站的注册信息 */ static void staisftics(){ }}
3 接口的实现
接口是抽象的,不能创建对象
因此在使用接口之前需要定义一个实现类,实现该接口
实现接口使用implements关键字实现
当一个类实现接口后。必须实现该接口的抽象方法
4.接口的使用
1.接口常量的使用,使用格式是接口名.常量名
2.接口中的抽象方法的使用·不能直接实现父类,我们实现他的子类
3.接口中默认方法的使用
接口中的默认方法可以被实现类(子类)(重写)
4接口中静态方法的使用
接口中的静态方法通过接口名.方法名直接调用即可
6.私有静态方法的使用
私有静态方法外界无法访问,他只能通过静态方法调用
外界通过调用静态方法来调用
JAVA接口编程基础
接口继承接口
1.接口可以继承单个接口 单继承 子接口继承父接口 子继承父接口
1.接口可以继承多个接口 多继承 子接口继承父类接口,又继承母亲接口
public interface UserService extends LongService,registerService{ }
1.接口可以继承多层接口 多层继承 孙子继承父亲,父亲接口继承爷爷的接口
类和类之间的关系
。继承
子类可以继承父类,单继承
子类可以继承父类,父类可以继承爷爷类,多层继承
java类不支持多继承,java接口支持多继承
面向对象之多态
1.生活中的多态:同一个行为,不同的对象就有不同的表现形式,动物吃东西,小描吃鱼,熊猫吃竹子
java中的多态:动态是面向对象的三大特征之一,java的多态指的是成员方法的多态
同一个方法,对于不同对象有不同的实现
多态的三要素
1.要有继承或者实现的关系
1.类继承普通类
2.类继承抽象类
3.类实现接口
2.方法的重写
3.父类的引用指向子类的对象
Animal animal=new Cat(); animal.eat();
2.多态的特点
package Test.oop.polymorphism;public class Monkey extends Animal { public Monkey(String name){ super(); }@Override public void eat(Food food){ System.out.println(this.getName()+"正在吃"+food.getName()); }
package Test.oop.polymorphism;public class Banana extends Food { public Banana(String name){ super(); }}
package Test.oop.polymorphism;public class Zookeeper { public void feed(Animal animal,Food food){ animal.eat(food); }
package Test.oop.polymorphism;public class ZookeeperTest { public static void main(String[] args) { Zookeeper zookeeper=new Zookeeper(); Animal animal=new Monkey("猴子"); Food food=new Banana("泰国香蕉"); zookeeper.feed(animal,food); animal=new Tiger("东北虎"); food=new Meat("周围人"); }
package Test.oop.polymorphism;public class Food { private String name; public Food() { } public Food(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; }}
package Test.oop.polymorphism;public class Tiger extends Animal { public Tiger(String name){ super(name); }@Override public void eat(Food food){ System.out.println(this.getName()+"正在吃"+food.getName()); }}
package Test.oop.polymorphism;public class Meat extends Food{ public Meat(String name){ super(name); }}
提供代码的可扩展性
憋:不能访问特有的方法·
引用类型转型
引用类型转型的功能就是解决多态的弊端
向上转型:父类的类型 引用 =子类对象
Animal animal=new Cat();
向下转型:将父类转换成子类的类型
Monkey monkey=(Monkey)animal;
类型转换异常
instanceof运算符解决转换异常
如果变量是对应的类型,那么的结果true ,否则就是false
if(animal instanceof Tiger){ Tiger tiger=(Tiger)Animal; }
多态的应用场景
1.变量的态
public class Polymorphism { public static void main(String[] args) { Animal animal=new Cat(); animal.eat(); animal=new Panda(); animal.eat(); }}
2.形参的多态
及方法的形参定义成父类的类型,然后调用的时候利用多态传递子类型
public class Zookeeper { public void feed(Animal animal,Food food){ animal.eat(food); }}
public class ZookeeperTest { public static void main(String[] args) { Zookeeper zookeeper=new Zookeeper(); Animal animal=new Monkey("猴子"); Food food=new Banana("泰国香蕉"); zookeeper.feed(animal,food); animal=new Tiger("东北虎"); food=new Meat("周围人"); }}
3.返回值多态
方法返回值多态通常和形参数多态一起使用
/ * 获取动物信息 * @param * @return */ public Animal getAnimal(Animal animal){ return animal; }
接口编程的进阶
接口和多态
多态的三要素
1.要有实现的关系,也就是实现实现类实现接口
2.方法的重写
3接口的引用指向实现类的对象
接口 对象接口=new 指向对象的接口
优点提供代码的可扩展性
憋:不能访问特有的方法·
引用类型转型
多态的应用场景
1.变量的多态
2.形参多态
package Test.oop.interfaces.service.impl;public class Computer { public void showComputerUSBDeviceInfe(USB usb1,USB usb2){ System.out.println("电脑的第一个USB接口连接设备是"+usb1.getDeviceInfo()); System.out.println("电脑的第两个个USB接口连接设备是"+usb2.getDeviceInfo()); }}
package Test.oop.interfaces.service.impl;public class ComputerTest { public static void main(String[] args) { Computer computer=new Computer(); USB usb1=new Mose(); USB usb2=new HardDisk(); computer.showComputerUSBDeviceInfe(usb1,usb2); }}
package Test.oop.interfaces.service.impl;public class HardDisk implements USB{ @Override public String getDeviceInfo() { return "没有硬盘"; }}
package Test.oop.interfaces.service.impl;public interface USB { / * 获取USB接口的信息 * @return */ String getDeviceInfo();}
package Test.oop.interfaces.service.impl;public class Mose implements USB{ @Override public String getDeviceInfo() { return "罗技"; }}
package Test.oop.interfaces.service.impl;public class Keyboard implements USB{ @Override public String getDeviceInfo() { return"键盘"; }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XVD8H2Hv-1654435923248)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220510205331087.png)]
案例2:对对象数组排序
回调接口
package Test.oop.interfaces;public class Cellphone { private String model; private String brand; private Integer price; private String color; private Integer weight; public Cellphone() { } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public Integer getWeight() { return weight; } public void setWeight(Integer weight) { this.weight = weight; }}
package Test.oop.interfaces.service.impl;import Test.oop.interfaces.Cellphone;public class SortTest { public static void main(String[] args) { } public static void sort(Cellphone[] cellphones){ for (int i = 0; i <cellphones.length ; i++) { for (int j = 0; j <cellphones.length-1-i; j++) { if (cellphones[j].getPrice()>cellphones[j+1].getPrice()){ Cellphone tmp=cellphones[j]; cellphones[j]=cellphones[j+1]; cellphones[j+1]=tmp; } } } }}
package Qaas;import java.util.Objects;public class Cellphone1 { private String model; private String brand; private Integer price; private String color; public String getModel() { return model; } public void setModel(String model) { this.model = model; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Integer getPrice() { return price; } public void setPrice(Integer price) { if (price < 0) { this.price = -1; return; } this.price = price; } public String getColor() { return color; } public void setColor(String color) { this.color = color; }}
代码需要重新写
3. 抽象类和接口
抽象类和接口的比较
相同
抽象类和接口都不能实例化
抽象类和接口都会编译成字节码文件
都可以声明对象的引用
都具备Object类的所有方法
都可以写抽象方法
不同点
。子类只能继承一个抽象类,子类可以实现多个接口
。接口中的成员变量都是常量,抽象类可以定义成员变量
。接口中没有构造方法 ,构造代码块,静态代码块
。接口中所有抽象方法必须是public abstract,不能包含普通方法,抽象类可以包含成员方法
内部类
1.内部类的概述
内部类:在一个类中定义另一个完整的了类
内部类的作用是给外部类提供完整的服务的
内部类编译后会生成一个独立的class文件
内部类访问外部类的私有成员,不会破坏封装性
内部类的按照不同修饰符和定义的位置分为以下几类
。成员内部类
。静态内部类
。局部内部类
。匿名内部类
2成员内部类
package Test.oop.innerclass;public class MemberlnnerClass { private String name; public MemberlnnerClass(String name){ } class InnerClass{ private String name; public InnerClass(String name) { this.name = name; } / * 查看成员信息 */ public void showMemberInfo(String name){ System.out.println("形参name="+name); System.out.println("内部类成员变量 name="+this.name); System.out.println("外部类成员变量 name=" + MemberlnnerClass.this.name); } }}
package Test.oop.innerclass;public class MemberInnerClassTest { public static void main(String[] args) { MemberlnnerClass memberlnnerClass=new MemberlnnerClass("外部类"); MemberlnnerClass.InnerClass innerClass=memberlnnerClass.new InnerClass("内部类"); innerClass.showMemberInfo("形参"); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Rdy9RGO-1654435923249)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220510231052974.png)]
静态内部类
成员内部类定义在类中,和成员变量,成员方法平级,成员内部类使用static修饰
。成员内部类创建对象不需要依赖外部类的对象
。成员内部类能包含静态成员(静态变量,静态方法)
。内部类编译生成的字节码文件格式是 外部类$内部类.class
。静态内部类不能访问外部非静态的成员
package Test.oop.innerclass;public class StaticlnnerClass { static int count =10; static class InnerClass{ static int count=20; public void showStaticMemberInfo(int count){ System.out.println("形参 count="+count); System.out.println("内部类的静态成员 count="+InnerClass.count); System.out.println("外部类的静态成员 count="+StaticlnnerClass.count); } }}
package Test.oop.innerclass;public class StaticlnnerClassTest { public static void main(String[] args) { StaticlnnerClass.InnerClass innerClass=new StaticlnnerClass.InnerClass(); innerClass.showStaticMemberInfo(40); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gsGTr2zW-1654435923250)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511154310688.png)]
静态内部类实现单例模式
package Test.oop.innerclass;public class StaticInnerClassSingletonTest { public static void main(String[] args) { StaticInnerClassSingleton staticInnerClassSingleton=StaticInnerClassSingleton.getInstance(); System.out.println(StaticInnerClassSingleton.getInstance()); System.out.println(StaticInnerClassSingleton.getInstance()); System.out.println(StaticInnerClassSingleton.getInstance()); System.out.println(StaticInnerClassSingleton.getInstance()); System.out.println(StaticInnerClassSingleton.getInstance()); System.out.println(StaticInnerClassSingleton.getInstance()); }
package Test.oop.innerclass;public class StaticInnerClassSingleton { / *私有化构造器 */ private StaticInnerClassSingleton(){}public static StaticInnerClassSingleton getInstance(){ return StaticInnerClassSingletonHolder .INSTANCE;} private static class StaticInnerClassSingletonHolder{ private static final StaticInnerClassSingleton INSTANCE=new StaticInnerClassSingleton(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hW8NHU5w-1654435923251)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511154545362.png)]
局部内部类
JDK源码中的内部类使用实例 java.lang.Integerz中有
局部内部类定义在方法中,只能在方法中使用。局部内部类在日常开发中几乎用不到
讲局部内部类是为了让大家理解匿名内部类
.局部内部类中使用了方法的局部变量,那么这个局部变量默认就使用final修饰
。局部内部类不能定义静态成员
。局部内部类只能使用默认访问的权限,只是作为方法的局部变量的存在
。局部内部类编译后的格式外部类$序号.class
public static void main(String[] args) { class InnerClass{ private String name; InnerClass(String name){ this.name=name; } public void showLMemberInfo(){ System.out.println(this.name); } } InnerClass innerClass =new InnerClass("局部内部类"); innerClass.showLMemberInfo(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TIAjNZR4-1654435923251)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511172132473.png)]
package Test.oop.innerclass;public class LocallnnerClassTest { public static void main(String[] args) { int number=10; class InnerClass{ private String name; InnerClass(String name){ this.name=name; System.out.println("main() 方法的局部变量="+number); } public void showLMemberInfo(){ System.out.println(this.name); } } InnerClass innerClass =new InnerClass("局部内部类"); innerClass.showLMemberInfo(); }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VT2tUmMl-1654435923252)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511172414664.png)]
匿名内部类
匿名对象 没有名字的对象
匿名内部类表示没有名字的局部内部类
.一切特征和局部内部类相同
.必须继承一个父类或者父类或者继承一个接口,因为通常都是和抽象类,接口结合使用
package Test.oop.innerclass;import Test.oop.abstracts.Animal;public class AnonymityInnerClassTest { / * 匿名内部类 没有名字的局部内部类 * @param args */ public static void main(String[] args) {Animal animal= new Animal(){ @Override public void eat() { System.out.println("大熊猫在吃竹子"); } @Override public void sleep(String nationality) { System.out.println(nationality+"大熊猫正在睡觉"); } };animal.eat();animal.sleep("中国四川"); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z4X3Hh80-1654435923253)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511174639946.png)]
.将定义类(实现抽象方法 ),创建对象对象的和并在一块了,只能创建一个该类的对象
类的初始化机制
.成员变量
.静态变量
.构造方法
.构造代码块
。静态代码块
。内部类 懒加载特性,只有使用的时候才会加载。例如执行创建内部类的对象,内部类的静态代码块一定会执行
SubClass.InnerClass innerClass=new SubClass.InnerClass();
package Test.oop.initiallization;public class SubClass { public SubClass() { System.out.println("3.子类执行的无参代码块"); } //构造代码块 { System.out.println("2.子类执行构造代码块"); } //静态代码块 static { System.out.println("1.子类执行静态代码块"); }}
package Test.oop.initiallization;public class ClassMemberInitalizationOrderTest { public static void main(String[] args) { new SubClass(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDhBYtm2-1654435923254)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511181518590.png)]
1.子类的初始化机制
package Test.oop.initiallization;public class SubClass { public SubClass() { System.out.println("3.子类执行的无参代码块"); } //构造代码块 { System.out.println("2.子类执行构造代码块"); } //静态代码块 static { System.out.println("1.子类执行静态代码块"); } / * 显示初始化成员变量赋值 * 默认初始化 */ private String memberVariable=initMemberVariable(); private String initMemberVariable() { System.out.println("子类执行显示初始化成员变量赋值"); return "我是一个成员变量"; } private static String staticVarianble=initStatiVariable(); private static String initStatiVariable() { System.out.println("我是一个静态变量"); return "我是一个静态变量"; } static class InnerClass{ static { System.out.println("执行子类的静态内部类的静态代码块"); } }}
package Test.oop.initiallization;public class ClassMemberInitalizationOrderTest { public static void main(String[] args) { new SubClass(); SubClass.InnerClass innerClass=new SubClass.InnerClass(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hYRCBwd-1654435923255)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511183920011.png)]
1.步骤1和步骤2优先相同,因为都是静态的 ,那个首第一步执行 取决于定义的顺序
步骤3和步骤第四个优先级相同,首先执行,取决于首先变量赋初值
变量(成员变量,静态变量在显示初始化赋值之前,系统看到会先给变量赋初值
2.父类的初始化机制
package Test.oop.initiallization;public class SubClass extends SuperClass { public SubClass() { System.out.println("3.子类执行的无参代码块"); } //构造代码块 { System.out.println("2.子类执行构造代码块"); } //静态代码块 static { System.out.println("1.子类执行静态代码块"); } / * 显示初始化成员变量赋值 * 默认初始化 */ private String memberVariable=initMemberVariable(); private String initMemberVariable() { System.out.println("子类执行显示初始化成员变量赋值"); return "我是一个成员变量"; } private static String staticVarianble=initStatiVariable(); private static String initStatiVariable() { System.out.println("我是一个静态变量"); return "我是一个静态变量"; } static class InnerClass{ static { System.out.println("执行子类的静态内部类的静态代码块"); } }}
package Test.oop.initiallization;//父类public class SuperClass { public SuperClass() { System.out.println("3.父类执行的无参代码块"); } //构造代码块 { System.out.println("2.父类执行构造代码块"); } //静态代码块 static { System.out.println("1.父类执行静态代码块"); } / * 显示初始化成员变量赋值 * 默认初始化 */ private String memberVariable=initMemberVariable(); private String initMemberVariable() { System.out.println("父类执行显示初始化成员变量赋值"); return "我是一个成员变量"; } private static String staticVarianble=initStatiVariable(); private static String initStatiVariable() { System.out.println("我是一个静态变量"); return "我是一个静态变量"; } static class InnerClass{ static { System.out.println("执行父类的静态内部类的静态代码块"); } }}
package Test.oop.initiallization;public class ClassMemberInitalizationOrderTest { public static void main(String[] args) { new SubClass(); SubClass.InnerClass innerClass=new SubClass.InnerClass(); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ct7wRCjU-1654435923256)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511190432725.png)]
java枚举
枚举和java类一样,也是一种引用数据类型,其应用场景就是取消范围比较固定的数据
。季节 春夏秋冬
。星期 星期一到星期天
。月份
。枚举的好处就是可以提高程序的可读性,增加数据的安全性
枚举也是JAVA也是JAVA.LANG.OBJECT的子类
java.lang.Enum是所有java枚举的父类
枚举也是可以实现接口的;
枚举的定义和使用
枚举定义的格式
public enum EnumName{}
枚举的成员
.枚举值
,枚举值本质就是常量
public static final Seasom SPRING=new Season
.构造方法
。构造方法的访问权限默认是私有的,构造方法给枚举值初始化
private Seasom(){ System.out.println("枚举的实例被初始化了"); }
。成员变量
private String description;
.成员方法
public String getDescription() { return description; } public void setDescription(String description) { this.description = description; }
.静态方法
/ * 根据描述获取枚举值实例(枚举值) * @param description 描述 * @return 枚举 */ public static Seasom getSeasonByDescription(String description){ for (Seasom value : Seasom.values()) { if (description.equals(value.getDescription())); return value; } return null; }
.重写父类Object的方法
@Override public String toString() { return "季节{" + "季节描述='" + description + '\'' + '}'; }
.枚举值
枚举的使用
SPRING ,SUMMER,AUTUMN,WINTER;
package Test.oop.enums;public class EnumTest { public static void main(String[] args) { Seasom spring=Seasom.SPRING; System.out.println(spring); }}
package Test.oop.enums;/ * 枚举季节 * public static final Seasom SPRING=new Season * */public enum Seasom { SPRING("春天") ,SUMMER("夏天"),AUTUMN("秋天"),WINTER("冬天"); /* 枚举构造方法/ //Seasom(){ // System.out.println("枚举的实例被初始化了"); // } private String description; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "季节{" + "季节描述='" + description + '\'' + '}'; } / * 根据描述获取枚举值实例(枚举值) * @param description 描述 * @return 枚举 */ public static Seasom getSeasonByDescription(String description){ for (Seasom value : Seasom.values()) { if (description.equals(value.getDescription())); return value; } return null; } Seasom(String description){this.description=description; }}
package Test.oop.enums;public class EnumTest { public static void main(String[] args) { Seasom spring=Seasom.SPRING; System.out.println(spring); Seasom.getSeasonByDescription("春天"); System.out.println(spring.getDescription()); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z6FwVQrM-1654435923257)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220511210200416.png)]
package Test.oop.enums;import Test.oop.interfaces.UserService;public class RegisterSource1Test { UserService userService; / * 注册来源 * @param registerSource1 */ public void handleRegisterSource(RegisterSource1 registerSource1){ switch (registerSource1){ case PC: break; case ANDROID_APP: break; case IOS_APP: break; case WE_CHAT: break; default: break; } } public static void main(String[] args) { }}
package Test.oop.enums;public enum RegisterSource1 { ANDROID_APP("安装"),IOS_APP("苹果"),WE_CHAT("微信"),PC("窗"),UNKONW("未知的"); private String description; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } RegisterSource1(String description){ this.description=description; }}
需要完善代码
TestNG的基本使用
1J.ava项目集成TestNG
官网地址:TestNG - 欢迎
因为java项目是Maven项目,配置阿里云的私服(公司的服务器)
1.定义版本属性
<testng.version>7.6.0</testng.version>
2.定义版本和作用域
<dependencyManagement> <dependencies> <!-- https://mvnrepository.com/artifact/org.testng/testng --> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>${testng.version}</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
3.添加依赖
2.TestNG框架的基本使用
TestNG常用的注解
1.@Test注解使用
在测试方法上标记应该注解,该方法就可以像main方法运行,那样我们程序不需要借助main方法的使用
@Test public void testTestAnnotation(){ System.out.println("哈哈"); }
2.@BeforeMethod注解
- @AfterMethod注解
- @BeforeClass注解
- Afterclass注解
断言的基本使用
3.TestMe插件的使用
Objects类的使用
1.Objects类的介绍
java.util.Objects类是操作对象的工具类,包含一些操作对象的静态方法,这些静态方法可以防止空指针异常,或者说可以容忍空指针
Objects类是jdk1.7中使用
2.Objects类的常用方法的使用
1.equals()方法的使用
其他JDK提供API的equals()方法是不能防止空指针异常
package api.util;public class ObjectsTest1 { @Test public void testStringEquals(){ String str1=null; String str2="zxszxc"; System.out.println(str1.equals(str2)); }}
@Test public void testObjectsEquals(){ String str1=null; String str2="zxs"; boolean result= Objects.equals(str1,str2); //段言结果成立不报错Assert.assertEquals(result,false);
因此尽量去使用Objects提供的equals()方法,比较两个数字是否相等,可以防止空指针异常
他是怎么防止空指针异常的
Object a, Object b表示方法可以接收任何Obejct子类类型的数据,也就是形参多态
public static boolean equals(Object a, Object b) { / *a=null; *b="tony"; *1.判断a和b的地址是否相等,如果相等直接返回true,由于短路或的短路特性 有一个为true,整体表达式为true 2.由于a不等于b,因此执行a!=null,所以a!=null的结果是false,由于短路与的特性,因此a.equals(b)不会执行,避免空指针。 */ return (a == b) || (a != null && a.equals(b)); }
2.nonNull()方法的使用
@Test public void testObjectNull(){ String str=""; System.out.println(Objects.nonNull(str)); }
源码如下Objects的nonNULL方法的源码
public static boolean nonNull(Object obj) { return obj != null; }
objects和requireNonNull方法如果是传递的null,就会抛出NPE异常
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) { if (obj == null) throw new NullPointerException(messageSupplier.get()); return obj; }}
随机数的应用
手机短信的验证码
随机密码
斗地主的发脾
Random类的使用
package api.util;import java.util.Random;public class RandomTest { @Test public void testRanom(){ //产生10个随机数的取值范围是int的取值范围 Random random=new Random(); for (int i = 0; i <10 ; i++) { System.out.println(random.nextInt()+""); } }}
随机数是靠种子数子生成的,如果种子数相同,那么生成的随机序列也相同,产生了重复的随机序列
日常开发中通常都不会指定种子数
// @Test public void testRanomSeed(){ Random random=new Random(88); for (int i = 0; i <10 ; i++) { System.out.println(random.nextInt()+""); } }
如果不指定种子数,系统会生成种子数
public Random() { this(seedUniquifier() ^ System.nanoTime()); }
手机短信验证码
package api.util;public class RandomUtils { public static String verificationCode(int length){ if (length==4||length==6){ char[]chars=new char[length]; for (int i = 0; i < length; i++) { char[i]=('0'+random.nextInt(10); } }else { throw new RuntimeException("手机验证码的长度不合理"); } return new String(char); }}
package api.util;import java.util.Random;public class RandomUtilsTest { @Test public void testVerificationCode(){ System.out.println(Random.verificationCode(4)); }}
ThreadlocalRandom类的使用
虽然Random类是线程安全的。但是高并发场景下还是使用ThreadlocalRandom
密码由大写字母,小写字母,数字以及特殊字符(!@#$%^&*)组成
Arrays类的使用
1.Arrays类的介绍
java.util.Arrays是一个包含操作数组的静态方法,例如数组的排序,查找,复制
日常开发项目时数组使用较少,因为长度不能改变,不够灵活,不过JDK数组封装了ArrayList
2.Arrays类的常用方法使用
排序方法的使用
查找方法的使用
java集合框架
Collection接口的使用
1.Collection接口的介绍
Collection接口所有单例集合的顶级接口,该接口没有直接的实现类,如果要使用Collection接口中的方法,那么就要使用Set接口或者List接口的实现类 例如ArrayList,HashSet类来实现接口,因为接口不能实例化,ArrayList实现了Collection接口的所有抽象方法
Collection接口中的抽象方法,所有单列集合实现类都实现了
2.Collection接口常用方法的使用
Collection接口常用的方法操作的都是字符串,为了让大家理解方法的使用
日常开发中集合通常操作的是自定义的类
.add(E e)往集合中添加指定的元素,就是Object类的子类对象
.boolean addAII(Collectionc);往集合添加一个另外一个集合
package util;import org.junit.Test;import java.util.ArrayList;import java.util.Collection;public class CollectionTest { / * @see java.util.Collection#add(Object) * @see java.util.Collection#addAll(Collection) */ @Test public void testCollectionAddAll(){ //创建一个集合对象,规定了集合储存的元素必须是字符串 Collection<String> collection=new ArrayList<String>(); collection.add("北京"); System.out.println("当前集合的元素:"+collection); //子集合 //多态 Collection<String>subCollection=new ArrayList<String>(); subCollection.add("北京"); subCollection.add("上海"); collection.addAll(subCollection); System.out.println("将subCollection的全部元素添加到collection集合-当前集合元素:"+collection); }}
2.判断指定元素是否包含指定元素,也可以是整个集合
.contains(Object o)判断指定的单个元素是否存在
.containsAll(Collectionc);判断指定的集合元素是否存在
/ * 判断指定元素是否包含指定元素 * @see java.util.Collection#add(Object) * @see java.util.Collection#containsAll(Collection) */ @Test public void testCollectionContainsAll(){ boolean isContains=collection.contains("北京"); System.out.println("collection"+isContains); Collection<String> samcollection=new ArrayList<String>(); samcollection.add("北京"); samcollection.add("上海"); samcollection.add("广州"); samcollection.add("深圳"); boolean isSame=collection.containsAll(samcollection); System.out.println("collection集合中是包含samcollection集合的全部元素"+isSame); collection.equals(samcollection); System.out.println(collection.equals(samcollection)); }
3.删除集合中指定的元素
1.删除单个元素
boolean remove(Object o); @Testpublic void testcollectionRemoveAll(){ collection.remove("深圳"); System.out.println("删除之后当前collection集合的元素"+collection);}}
2.删除指定的集合
boolean containsAll(Collection<?> c);
集合属性相关方法
.size()返回元素的个数
.isEmpty();集合中是否存在元素
@Test public void testCollectionSizeIsEmpty(){ System.out.println("当前集合元素的个数"+collection.size()); System.out.println("当前collection集合是否为空(是否没有元素)"+collection.isEmpty()); } @Test public void testCollectionSizeIsEmpty(){ System.out.println("没有清空之前集合元素的个数"+collection.size()); System.out.println("没有清空之前当前collection集合是否为空(是否没有元素)"+collection.isEmpty()); collection.clear(); System.out.println("清空之后集合元素的个数"+collection.size()); System.out.println("清空之后集合collection集合是否为空(是否没有元素)"+collection.isEmpty()); }
集合和数组的转换
@Test public void testCollection2Array(){ Object[]cities=collection.toArray(); for (Object city:cities) {System.out.println(cities); } List<String> anotherCities = Arrays.asList("河南","云南","昆明"); for(String anotherCity:anotherCities){System.out.println(anotherCity); } }
包装类
string不是包装类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssdxxswF-1654435923259)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604200941752.png)]
public class TestDemo10 { public static void main(String[] args) {Integer a=123;//装箱 装包 int b=a;//拆相 拆包 System.out.println(a+" "+b); }}
public class TestDemo10 { public static void main(String[] args) {Integer a=123;//装箱 装包 int b=a;//拆相 拆包 System.out.println(a+" "+b); System.out.println("========="); Integer a2=Integer.valueOf(123); Integer a3=new Integer(123); int b2=a2.intValue();//显示拆包 double d=a2.doubleValue();//显示的装包 int i=10;//显示的初始化 }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8m8fAwW4-1654435923260)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604205147707.png)]
List打印的方法
import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class TestDemo24 { public static void main(String[] args) { List<String>list=new ArrayList< >(); ArrayList<String>list1=new ArrayList<>(); list1.add("zxs"); list1.add("哈哈"); list1.add("zxc"); System.out.println(list1); System.out.println("=============="); for (int i = 0; i < list1.size(); i++) { System.out.println(list1.get(i)+" "); } System.out.println( " "); System.out.println("=================");for(String s:list1){ System.out.println(s+" ");} System.out.println(); System.out.println("=======迭代器打印========"); Iterator<String> it=list1.iterator(); while (it.hasNext()){ System.out.println(it.next()+" "); } //使用另外一个ArrayList和list进行初始化// ArrayListlist2=new ArrayList(); }}
System.out.println("=======迭代器打印========");// Iterator it=list1.iterator(); ListIterator<String>it1=list1.listIterator(); while (it1.hasNext()){ System.out.println(it1.next()+" "); }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ppi5Roz6-1654435923261)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604212422977.png)]
System.out.println("=======迭代器打印========");// Iterator it=list1.iterator(); ListIterator<String>it1=list1.listIterator(); while (it1.hasNext()){ String ret= it1.next(); if (ret.equals("zxc")){ it1.remove(); }else { System.out.println(ret+" "); } //System.out.println(it1.next()+" "); }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tfBLwx7H-1654435923261)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604213251570.png)]
首先需要使用next方法迭代集合中的元素,然后才能调用remove方法,否则集合可能会因为对同一个list remove多次会抛出异常
2.remove删除元素的
import java.util.ArrayList;public class TestDome17 { public static void main(String[] args) { ArrayList<String>list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); // String ret=list2.remove(0); boolean ret=list2.remove("a"); System.out.println(ret); System.out.println(list2); }}
3.使用get方法
import java.util.ArrayList;public class TestDome16 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); String ret=list2.get(2); System.out.println(ret); System.out.println(list2); } }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ptI0wLjW-1654435923262)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604221307990.png)]
4.使用set方法
import java.util.ArrayList;public class TestDome15 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); String ret=list2.set(2,"zxs"); System.out.println("原来的字符串"+ret); System.out.println(list2); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QC5ucbao-1654435923262)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604221918426.png)]
5.clear方法的使用
import java.util.ArrayList;public class TestDome14 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); list2.clear(); System.out.println(list2); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FqjY4YjH-1654435923263)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604222426761.png)]
6.contains方法的使用
import java.util.ArrayList;public class TestDome14 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); System.out.println(list2.contains("c")); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w2JfRGML-1654435923263)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604222817789.png)]
7.indexOf方法的使用
import java.util.ArrayList;public class TestDome14 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("c"); System.out.println(list2); System.out.println(list2.indexOf("c")); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QbhiP3oP-1654435923264)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604223101454.png)]
8.lastIndexOf方法的使用
import java.util.ArrayList;public class TestDome14 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("z"); System.out.println(list2); System.out.println(list2.lastIndexOf("z")); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6crB8AH9-1654435923264)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220604223445797.png)]
9,subList方法的使用打印数组的元素
public class TestDome14 { public static void main(String[] args) { ArrayList<String> list2=new ArrayList<>(); list2.add("a"); list2.add("b"); list2.add("z"); list2.add("s"); list2.add("d"); list2.add("y"); List<String> sub=list2.subList(0,6); System.out.println(sub); System.out.println(list2); System.out.println("============"); sub.set(0,"p"); System.out.println(sub); System.out.println(list2); }}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9q8iPe8-1654435923265)(C:\Users\风与行\AppData\Roaming\Typora\typora-user-images\image-20220605190136905.png)]
ArrayList虽然是数组,但是当前这个数组没有大小,大小为0,既然数组大小是0,那么存放这个元素的时候,为什么成功没有越界,
在进行分配的时候初始的大小是0,当我们第一次存放数据元素的时候,顺序表被分配的大小为10,
结论:
1.如果ArrayList调用,不带参数构造方法,那么顺序表的大小是0,当第一次add的时候,整个顺序表才变为了10
当这个10个放满了,开始扩容,以1.5倍的方式进行扩容,
2.如果调用的是给定容量的构造方法,那么你的顺序表大小,就是你给定的容量,放满了还是1.5倍的进行扩容
模拟实现List
import java.util.Arrays;class ArrayList<E> { private Object[] elementData;//数组 private int usedSize;//代表有效的数据个数 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(int capacity) { //对参数进行一个判断 if (capacity > 0) { this.elementData = new Object[capacity]; } else if (capacity == 0) { this.elementData = new Object[0]; } throw new IllegalArgumentException("初始化的容量不能为负数"); } / * 添加元素 相当于存放在了数组的最后的位置 * @param e 数据 * @return */ public boolean add(E e ){ //确定实际容量,预测->扩容 ensureCapacityInternal(usedSize+1); elementData[usedSize]=e; usedSize++; return true; } private void ensureCapacityInternal(int minCapacity){ //1.计算出需要的容量 int capacity=calculateCapacity(elementData,minCapacity); //2.拿着计算机出的容量,去看,满了扩容,空的 ensureExplicitCapacity(capacity); } private void ensureExplicitCapacity(int minCapacity) { // overflow-conscious code //进不去if语句,数组还没有方满 if (minCapacity - elementData.length > 0) //扩容了 grow(minCapacity); } private static final int MAX_ARRAY_SIZE= Integer.MAX_VALUE-8; private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - Integer.MAX_VALUE-8 > 0) //说明你要的容量非常大 newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } private static int calculateCapacity(Object[] elementData,int minCapacity ){ //1.是否之前elementData数组分配过大小 if (elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){ return Math.max(10,minCapacity); } //2.分配过 就返回+1的值 return minCapacity; } /* * * @param index * @param e */ public void add(int index,E e){ //1/检查下标是否合法 rangeCheckForAdd(index); //确定容量 ensureCapacityInternal(usedSize+1); //3.那数据 copy(index,e); usedSize++; } private void copy(int index,E e){ for (int i = usedSize-1; i >=index; i--) { elementData[i+1]=elementData[i]; } } private void rangeCheckForAdd(int index){ if (index<0||index>size()){ throw new IndexOutOfBoundsException("index位置不合法,不能插入!"); } } public int size(){ return this.usedSize; }}public class TestDemo12 { public static void main(String[] args) { ArrayList<String>list=new ArrayList<>(); list.add("ab"); list.add("abc"); list.add("abcd"); list.add("abcde"); list.add(0,"zxs"); System.out.println("dfdehdyrj"); }}