小黑子—Java从入门到入土过程:第六章
Java零基础入门6.0
- Java系列第六章
-
- 1. 面向对象综合练习
-
- 1.1 文字版格斗游戏
-
- 参数占位,格式化输出回顾
- 关于printf和print和println的区别
- 1.2 对象数组练习
-
- 1.2.1 练习一
- 1.2.2 练习二
- 1.2.3 练习三
- 1.2.4 练习四
- 1.3 键盘录入回顾
- 1.4 复杂对象数组练习
-
- 1.4.1 复杂练习一
- 1.4.2 复杂练习二
- 2. API:应用程序编程接口
-
- 2.1 使用帮助文档
- 3. 字符串String
-
- 3.1 创建String对象的两种方式
- 3.2 字符串的比较
- 3.3 字符串练习
-
- 3.3.1 练习一:用户登录
- 3.3.2 练习二 ctrl+alt+v 自动生成左边赋值
- 3.3.3 练习三:字符串拼接和反转
- 3.3.4 练习四
- 3.3.5 练习五
- 3.4 StringBuilder
-
- 3.4.1 StringBuilder构造方法
- 3.4.2 StringBuilder常用方法
- 3.4.3 链式编程
- 3.4.4 StringJoiner
- 3.4.5 字符串原理
-
- 扩展底层原理1和2:字符串原理
- 扩展底层原理3:字符串拼接的底层原理
- 扩展底层原理5:StringBuilder提高效率原理
- 扩展底层原理5:StringBuilder源码分析
- ctrl + n IDEA快捷键 出现搜索界面
- 3.4.6 字符串综合练习
- 4. 集合
-
- 4.1 ArrayList 集合(之一)
- 4.2 集合综合练习
-
- 4.2.1 添加字符串和整数遍历
- 4.2.2 基本数据类型的包装类
- 4.2.3 添加学生对象并遍历
- 4.2.4 添加用户对象并判断是否存在
- 4.2.5 添加手机对象并返回要求的数据
- 5. 学生管理系统
-
- 5.1 学生管理系统升级版
- 6. 面向对象进阶
-
- 6.1 static
-
- 6.1.1 static-静态变量
- 6.1.2 static-静态方法和工具
-
- 静态方法
- 工具类
- 6.1.3 static-注意事项
- 6.1.4 重新认识main方法
- 6.2 继承
-
- 6.2.1 封装
- 6.2.2 继承的描述
- 6.2.3 继承的特点
- 6.2.4 子类继承父类的特性
- 6.2.5 终端的jps和jhsdb hsdb
- 6.2.6 继承中成员变量和成员方法的访问特点
- 6.2.6 继承中的构造方法
- 6.2.7 thissuper关键字
- 6.10 认识多态
- 6.11 多态中调用成员的特点
- 6.12 多态的优势和弊端
- 6.13 多态综合练习
- 6.14 包和final
- 6.15 权限修饰符和代码块
- 6.16 抽象类和抽象方法
- 6.17 接口
- 6.18 接口的细节:成员特点和各种接口的关系
- 6.19 接口和抽象类案例
- 6.20 接口应用和适配器设计模型(new way)
- 6.21 初始内部类
- 6.22 成员内部类
- 6.23 静态内部类
- 6.24 局部内部类
- 6.26 匿名内部类
Java系列第六章
1. 面向对象综合练习
1.1 文字版格斗游戏
1.简单版
User类包
package test3;import java.util.Random;public class User {private String name;private int blood;private char gender;private String face;//长相随机String[] boyfaces = {"风流俊雅", "气宇轩昂", "相貌英俊", "五官端正", "相貌平平", "一塌糊涂", "面目狰狞"};String[] girlfaces = {"美奂绝伦", "沉鱼落雁", "婷婷玉立", "身材娇好", "相貌平平", "相貌简陋", "惨不忍睹"};//attack攻击描述:String[] attacks_desc = {"%s使出了一招【背心钉】,转到对方的身后,一掌向%s背心的灵台穴拍去。","%s使出了一招【游空探爪】,飞起身形自半空中变掌为抓锁向%s。","%s大喝一声,身形下伏,一招【劈雷坠地】,捶向%s双腿。","%s运气于掌,一瞬间掌心变得血红,一式【掌心雷】,推向%s。","%s阴手翻起阳手跟进,一招【没逛拦】,结结实实的挺向%s。","%s上步抢身,招中套招,一招【劈挂连环】,连环攻向%s"};//injured受伤描述:String[] injureds_desc = {"结果%s退了半步,毫发无损","结果给%s造成一处瘀伤","结果一击命中,%s痛得弯下腰","结果%s痛苦地闷哼了一声,显然受了点内伤","结果%s摇摇晃晃,一跤摔倒在地","结果%s脸色一下变得惨白,连退了好几步","结果『轰』的一声,%s口中鲜血狂喷而出","结果%s一声惨叫,像滩软泥般塌了下去",};public User() {}public User(String name, int blood, char gengder) {this.name = name;this.blood = blood;this.gender = gender;//随机长相setFace(gender);}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public String getFace() {return face;}public void setFace(char gender) {Random r = new Random();//长相随机if (gender == '男') {//从boyfaces里面随机长相int index = r.nextInt(boyfaces.length);this.face = boyfaces[index];} else if (gender == '女') {//从girlfaces里面随机长相int index = r.nextInt(girlfaces.length);this.face = girlfaces[index];} else {this.face = "面目狰狞";}}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getBlood() {return blood;}public void setBlood(int blood) {this.blood = blood;}//定义一个方法用于攻击别人//思考:谁攻击谁?//r1.攻击(r2)//方法的调用者去攻击参数public void attack(User user) {Random r = new Random();int index = r.nextInt(attacks_desc.length);String KungFu = attacks_desc[index];//输出一个攻击的效果System.out.printf(KungFu,this.getName(),user.getName());System.out.println();//计算造成的伤害int hurt = r.nextInt(20) + 1;//修改一下挨揍的人血量//剩余血量int remainBoold = user.getBlood() - hurt;//对剩余血量做一个验证,如果为负数了,就修改为0remainBoold = remainBoold < 0 ? 0 : remainBoold;//修改一下挨揍的人血量user.setBlood(remainBoold);//受伤的描述//血量>90 0 索引的描述//80 ~ 90 1索引的描述//70 ~ 80 2索引的描述// 60 ~ 70 3索引的描述// 40 ~ 60 4索引的描述// 20 ~ 40 5索引的描述// 10 ~ 20 6索引的描述// 小于10的 7索引的描述if(remainBoold > 90){System.out.printf(injureds_desc[0],user.getName());}else if(remainBoold>80&&remainBoold<=90){System.out.printf(injureds_desc[1],user.getName());}else if(remainBoold>70&&remainBoold<=80){System.out.printf(injureds_desc[2],user.getName());}else if(remainBoold>60&&remainBoold<=70){System.out.printf(injureds_desc[3],user.getName());}else if(remainBoold>40&&remainBoold<=60){System.out.printf(injureds_desc[4],user.getName());}else if(remainBoold>20&&remainBoold<=40){System.out.printf(injureds_desc[5],user.getName());}else if(remainBoold>10&&remainBoold<=200){System.out.printf(injureds_desc[6],user.getName());}else{System.out.printf(injureds_desc[7],user.getName());}System.out.println();}public void showRoleInfo() {System.out.println("姓名为" + getName());System.out.println("血量为" + getBlood());System.out.println("性别为" + getGender());System.out.println("长相为" + getFace());}
}
GameTest类包
package test3;public class GameTest {public static void main(String[] args) {// 1. 创建第一个角色User u1 = new User("麻瓜",100,'男');//2.创建第二个角色User u2 = new User("小老板",100,'男');//展示角色信息u1.showRoleInfo();System.out.println("------------------------");u2.showRoleInfo();System.out.println("------------------------");//3.开始格斗 回合制游戏while(true){//u1 开始攻击u2u1.attack(u1);//判断u2的剩余血量if(u2.getBlood()==0){System.out.println(u1.getName()+"K.O了"+u2.getName());break;}//u2开始攻击u1u2.attack(u1);if(u1.getBlood()==0){System.out.println(u2.getName()+"K.O了"+u1.getName());break;}}}
}
参数占位,格式化输出回顾
public static void main(String[] args) {//两部分参数://第一部分参数:要输出的内容%s(占位)// 第二部分参数:填充的数据System.out.printf("%s你好啊%s","张三","李四");//但是printf没有换行效果System.out.println();System.out.printf("你好啊%s","李四");}
关于printf和print和println的区别
- print为一般输出,同样不能保留精度格式转化,也不能换行输出
- printf常用于格式转换,但需要注意不是换行输出,只用于精度转换
- println为换行输出,不能用于格式转换
1.2 对象数组练习
1.2.1 练习一
Goods 类包
package test4;public class Goods {private String id;private String name;private double price;private int count;public Goods(){}public Goods(String id,String name,double price, int count){this.id = id;this.name = name;this.price = price;this.count = count;}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;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}
}
GoodsTest 引入执行
package test4;public class GoodsTest {public static void main(String[] args) {//1.创建一个数组Goods[] arr = new Goods[3];//2.创建三个商品//快捷键 ctrl+p :把方法所对应的参数所展示Goods g1 = new Goods("001","华为p40",599.0,100);Goods g2 = new Goods("002","保温杯",297,50);Goods g3 = new Goods("003","洗衣机",10000,500);//3.把商品添加到数组中arr[0]=g1;arr[1]=g2;arr[2]=g3;//4.遍历for (int i = 0; i < arr.length; i++) {// i 索引 arr[i] 元素Goods goods = arr[i];System.out.println(goods.getId()+","+goods.getName()+","+goods.getPrice()+","+goods.getCount());}}
}
1.2.2 练习二
Car的javabeen包
package test5;public class Car {private String brand;//品牌private int price;//价格private String color;//颜色public Car(){}public Car(String brand, int price, String color) {this.brand = brand;this.price = price;this.color = color;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}
}
CarTest
package test5;import java.util.Scanner;public class CarTest {public static void main(String[] args) {//1.创建一个数组用来存3个汽车对象Car[] arr = new Car[3];//2.创建汽车对象,数据来自于键盘录入//如果把Car c = new Car();放在循环的外面,那么对象就只有一辆车//此时下面循环就对同一辆车的属性进行修改,而不是创建新的属性//所以此创建对象的代码不能写在循环的外面,必须写在循环里面Scanner sc = new Scanner(System.in);for (int i = 0; i < arr.length; i++) {//创建汽车对象Car c = new Car();//录入品牌System.out.println("请输入汽车的品牌:");String brand = sc.next();c.setBrand(brand);//录入价格System.out.println("请输入汽车的价格:");int price = sc.nextInt();c.setPrice(price);//录入颜色System.out.println("请输入汽车的颜色:");String color = sc.next();c.setColor(color);//把汽车对象添加到数组当中arr[i]=c;}//3.遍历数组for (int i = 0; i < arr.length; i++) {Car car = arr[i];System.out.println(car.getBrand()+","+car.getPrice()+","+car.getColor());}}
}
1.2.3 练习三
Phone的javabeen包
package test6;public class Phone {private String brand;//品牌private int price;//价格private String color;//颜色public Phone(){}public Phone(String brand,int price,String color){this.brand = brand;this.price = price;this.color = color;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}
}
PhoneTest
package test6;public class PhoneTest {public static void main(String[] args) {//1.创建一个数组Phone[] arr = new Phone[3];//2.创建手机的对象Phone p1 = new Phone("xiaomi",1999,"white");Phone p2 = new Phone("huawei",4999,"blue");Phone p3 = new Phone("meizhu",2999,"red");//3.把手机对象添加到数组当中arr[0]=p1;arr[1]=p2;arr[2]=p3;//4.获取三部手机的平均价格int sum = 0;for (int i = 0; i < arr.length; i++) {//i索引 arr[i]元素(手机对象)Phone phone = arr[i];sum = sum + phone.getPrice();}//5.求平均值double avg = sum*1.0/arr.length;System.out.println(avg);}
}
1.2.4 练习四
GilFriend的javabeen包
package test7;public class GirlFriend {private String name;//姓名private int age; //年龄private String gender;//性别private String hobby;//爱好public GirlFriend() {}public GirlFriend(String name, int age, String gender, String hobby) {this.name = name;this.age = age;this.gender = gender;this.hobby = hobby;}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 getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getHobby() {return hobby;}public void setHobby(String hobby) {this.hobby = hobby;}
}
GirlFriendTest
package test7;public class GirlFriendTest {public static void main(String[] args) {//1.定义数组存入女朋友的对象GirlFriend[] arr = new GirlFriend[4];//2.创建女朋友的对象GirlFriend gf1 = new GirlFriend("小老板",22,"man","do the game");GirlFriend gf2 = new GirlFriend("麻瓜",24,"man","van the game");GirlFriend gf3 = new GirlFriend("马捞C",30,"man","乖乖站好");GirlFriend gf4 = new GirlFriend("阿克曼",18,"man","fk you");//3.把对象添加到数组当中arr[0]=gf1;arr[1]=gf2;arr[2]=gf3;arr[3]=gf4;//4.求和int sum =0;for (int i = 0; i < arr.length; i++) {GirlFriend gf = arr[i];//累加sum += gf.getAge();}//5.平均值int avg = sum/arr.length;//6.统计年龄比平均值低的有几个,打印他们的信息int count = 0;for (int i = 0; i < arr.length; i++) {GirlFriend gf = arr[i];if(gf.getAge()<avg){count++;System.out.println(gf.getName()+","+gf.getAge()+","+gf.getGender()+","+gf.getHobby());}}System.out.println("一共"+count+"个");}
}
1.3 键盘录入回顾
键盘录入:
第一套体系:
- nextInt();接收整数
- nextDouble();接收小数
- next();接收字符串
- 遇到空格,制表符,回车就停止接受。这些符号后面的数据就不会接受了
public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");//123 123int num1 = sc.nextInt();//123System.out.println(num1);System.out.println("请输入第二个整数:");int num2 = sc.nextInt();//123System.out.println(num2);}
当next中出现空格时,可会给下一个键盘的数据接受,就不会做键盘录入
2.
public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str1 = sc.next();System.out.println(str1);System.out.println("请输入第二个字符串:");String str2 = sc.next();System.out.println(str2);}
第二套体系:
- nextLine();接收字符串
遇到回车才停止录入
public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String line1 = sc.nextLine();System.out.println(line1);System.out.println("请输入第二个字符串:");String line2 = sc.nextLine();System.out.println(line2);}
但是重要的是,键盘录入的两套体系不能混用
弊端:
- 先用nextInt,再用nextLine会导致下面的nextLine接受不到数据
public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");int num = sc.nextInt();//123+回车System.out.println(num);//123System.out.println("请输入第一个字符串:");String line = sc.nextLine();System.out.println(line);//录入不了,就结束了}
1.4 复杂对象数组练习
1.4.1 复杂练习一
思考要求1和2思路:
1.创建一个长度为3的数组2.创建学生对象3.把学生对象添加到数组当中4.再次创建一个学生对象5.唯一性判断5.1已存在---提示重复5.2不存在---添加学生对象6.添加学生对象6.1老数组已经存满6.2老数组没有存满
Student的javabeen包:
package test8;public class Student {private int id;private String name;private int age;public Student() {}public Student(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}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;}
}
Test实现要求1和2:
package test8;public class Test {public static void main(String[] args) {//1.创建一个数组用来储存学生对象Student[] arr = new Student[3];//2.创建学生对象并添加到数组当中Student stu1 = new Student(1,"zhangsan",23);Student stu2 = new Student(2,"lisi",24);//3.把学生对象添加到数组当中arr[0]=stu1;arr[1]=stu2;//要求1:再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。Student stu4 = new Student(4,"zhaoliu",26);//唯一性判断//已存在--不用添加//不存在--就可以把学生对象添加进数组boolean flag = contains(arr,stu4.getId());if(flag){//已存在--不用添加System.out.println("当前id重复,请修改id后再进行添加");}else{//不存在--就可以把学生对象添加进数组//把stu4添加到数组当中//1.数组已经存满---只能创建一个新的数组,新数组的长度=老数组+1//2.数组没有存满--直接添加int count = getCount(arr);if(count==arr.length){//已经存满//创建一个新的数组,长度=老数组的长度+1//然后把老数组的元素,拷贝到新数组当中Student[] newArr = creatNewArr(arr);//把stu4添加进去newArr[count]=stu4;//要求2:添加完毕之后,遍历所有学生信息printArr(arr);}else{//没有存满//[stu1,stu2,null]//getCount获取到的是2,表示数组当中已经有了2个元素//还有一层意思:如果下一次要添加数据,就是添加到2索引的位置arr[count] = stu4;//要求2:添加完毕之后,遍历所有学生信息,这样写就与上方重复了//此时就又需要定义方法进行调用printArr(arr);}}}public static void printArr(Student[] arr){for (int i = 0; i < arr.length; i++) {Student stu = arr[i];if(stu!=null){System.out.println(stu.getId()+","+stu.getName()+","+stu.getAge());}}}//创建一个新的数组,长度=老数组的长度+1// 然后把老数组的元素,拷贝到新数组当中public static Student[] creatNewArr(Student[] arr) {Student[] newArr = new Student[arr.length+1];//循环遍历得到老数组中的每一个元素for (int i = 0; i < arr.length; i++) {//把老数组中的元素添加到新数组当中newArr[i]=arr[i];}//把新数组返回return newArr;}//定义一个方法判断数组中已经存了几个元素public static int getCount(Student[] arr){//定义一个计数器用来统计int count = 0;for (int i = 0; i < arr.length; i++) {if(arr[i]!=null){count++;}}//当循环结束之后,我就知道了数组中一共有几个元素return count;}//1.我要干嘛? 唯一性判断//2.我干这件事,需要什么才能完成?数组id//3.调用处是否需要继续使用方法的结果?public static boolean contains(Student[] arr,int id){//1 2 3 ----3是否存在for (int i = 0; i < arr.length; i++) {//依次获取到数组里面的每一个学生对象Student stu = arr[i];//如果没装满,stu获取的是null,用null调用其他的方法就会报错if(stu!=null){//获取数组学生的idint sid = stu.getId();//比较if(sid == id){return true;}}}//当循环结束之后,还没有找到一样的,那么就表示数组中要查找的id是不存在的。return false;}
}
1.4.2 复杂练习二
Test2实现需求3和4
package test8;public class Test2 {public static void main(String[] args) {//1.创建一个数组用来储存学生对象Student[] arr = new Student[3];//2.创建学生对象并添加到数组当中Student stu1 = new Student(1,"zhangsan",23);Student stu2 = new Student(2,"lisi",24);Student stu3 = new Student(3,"wangwu",25);//3.把学生对象添加到数组当中arr[0]=stu1;arr[1]=stu2;arr[2]=stu3;//要求3:通过id删除学生信息//如果存在,则删除,如果不存在,则提示删除失败。//要找到id在数组中对应的索引int index = getIndex(arr,2);if(index>=0){//如果存在,则删除arr[index]=null;//遍历数组printArr(arr);}else{//如果不存在,则提示删除失败System.out.println("当前id不存在,删除失败");}}//1.我要干嘛? 找到id在数组中的索引//2.我干这件事,需要什么才能完成?数组id//3.调用处是否需要继续使用方法的结果? 要public static int getIndex(Student[] arr,int id){for (int i = 0; i < arr.length; i++) {//依次得到每一个学生对象Student stu = arr[i];//对stu进行一个非空判断if(stu !=null){int sid = stu.getId();if(sid==id){return i;}}}//当循环结束之后,还没有找到就表示不存在return -1;}public static void printArr(Student[] arr){for (int i = 0; i < arr.length; i++) {Student stu = arr[i];if(stu!=null){System.out.println(stu.getId()+","+stu.getName()+","+stu.getAge());}}}
}
Test3实现要求5:
package test8;public class Test3 {public static void main(String[] args) {//1.创建一个数组用来储存学生对象Student[] arr = new Student[3];//2.创建学生对象并添加到数组当中Student stu1 = new Student(1,"zhangsan",23);Student stu2 = new Student(2,"lisi",24);Student stu3 = new Student(3,"wangwu",25);//3.把学生对象添加到数组当中arr[0]=stu1;arr[1]=stu2;arr[2]=stu3;//4.先要找到id为2的学生对于的索引int index = getIndex(arr,2);//5.判断索引if(index>=0){//存在,则将他的年龄+1岁Student stu = arr[index];//把原来的年龄拿出来int newAge = stu.getAge()+1;//把+1之后的年龄塞回去stu.setAge(newAge);//遍历数组printArr(arr);}else{//不存在,则直接提示System.out.println("当前id不存在,修改失败");}}//1.我要干嘛? 找到id在数组中的索引//2.我干这件事,需要什么才能完成?数组id//3.调用处是否需要继续使用方法的结果? 要public static int getIndex(Student[] arr,int id){for (int i = 0; i < arr.length; i++) {//依次得到每一个学生对象Student stu = arr[i];//对stu进行一个非空判断if(stu !=null){int sid = stu.getId();if(sid==id){return i;}}}//当循环结束之后,还没有找到就表示不存在return -1;}public static void printArr(Student[] arr){for (int i = 0; i < arr.length; i++) {Student stu = arr[i];if(stu!=null){System.out.println(stu.getId()+","+stu.getName()+","+stu.getAge());}}}}
2. API:应用程序编程接口
例子:
其他的API都是存储在JDK-API帮助文档.CHM
2.1 使用帮助文档
API使用步骤
java.lang
包(非常重要)使用java.lang
包时,不需要import进行导入
API帮助文档网站
可以寻找关键字
API文档练习
public static void main(String[] args) {//1.创建对象Scanner sc = new Scanner(System.in);System.out.println("请输入一个小数:");//2.接受一个小数double result = sc.nextDouble();//3.输出打印System.out.println(result);}
3. 字符串String
常见情况:
字符串概述:
注意:
总结:
3.1 创建String对象的两种方式
其有两种:
直接赋值和用new去构造一个方法
public static void main(String[] args) {//直接赋值String a="1111";//空参构造String b=new String();System.out.println("1"+b+"2");//传递字符串(了解)String c=new String("abc");//传递字符数组//应用环境:修改字符串 例如把abc 改成qbc//abc-->{'a','b','c'}-->{'q','b','c'}-->""qbcchar[] d={'w','s','s','b'};String e=new String(d);System.out.println(e);//传递字节数组//应用场景:在网络中传输的都是字节信息,把字节信息转换成字符串byte[] f={97,98,99,100};//这里不是把数字传递过去,而是把数字转成ASCLL表里的字符。String g=new String(f);System.out.println(g);}
字符串在内存中的存储方式
字符串常量池
只有直接赋值的字符串才会在这个空间中 在堆内存中
当串池中已经存在一个abc字符串时,再次给字符串变量赋值相同的值时,会直接复用之前相同字符串的地址。
每new一次,就会在堆空间创建一个新的空间,可能会造成内存的浪费
所以,还是推荐使用直接赋值创建字符串。
3.2 字符串的比较
==号比较的原理
字符串常见比较错误:
对于不同方式字符串的内容比较:
例如:
1.
public static void main(String[] args) {//1.创建两个字符串对象String s1 = new String("abc");String s2 = "Abc";//2.==号比较//基本数据类型:比的是数据值//应用数据类型:比的是地址值System.out.println(s1==s2);//false//3.比较字符串对象中的内容是否相等boolean result = s1.equals(s2);System.out.println(result);//4.比较字符串对象中的内容是否相等,忽略大小写boolean result2 = s1.equalsIgnoreCase(s2);System.out.println(result2);// true}
public static void main(String[] args) {//1.假设我现在键盘录入一个abcScanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str1 = sc.next();//abc 是new出来的//2.代码中再定义一个字符串abcString str2 = "abc";//3.用==比较,这两者能一样吗?System.out.println(str1 == str2);//false,为什么?直接赋值的和new出来的不一样//结论://以后只要想比较字符串的内容,就必须要用string里面的方法}
3.3 字符串练习
3.3.1 练习一:用户登录
public static void main(String[] args) {// 1.定义两个变量记录正确的用户名和密码String rightUsername = "zhangsan";String rightPassword = "123456";Scanner sc =new Scanner(System.in);//2.键盘录入用户名和密码for (int i = 0; i < 3; i++) {System.out.println("请输入用户名:");String username = sc.next();System.out.println("请输入密码:");String password = sc.next();//3.比较if(username.equals(rightUsername)&&password.equals((rightPassword))){System.out.println("用户登录成功");break;}else{if(i==2){// 最后一次机会也输入错误,此时要提示账号被锁定System.out.println("账号"+username+"被锁定");}else{System.out.println("用户登录失败,用户名或密码有误,您还剩下"+(2-i)+"次机会");//}}}}
3.3.2 练习二 ctrl+alt+v 自动生成左边赋值
chcharAt()方法:返回每一个索引对应的索引值
public static void main(String[] args) {// 1. 键盘录入一个字符串Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str = sc.next();//2.进行遍历for (int i = 0; i < str.length(); i++) {//i 依次表示字符串的每一个索引//chcharAt()方法:返回每一个索引对应的索引值// ctrl+alt+v 自动str.charAt(i);生成左边char c = str.charAt(i);System.out.println(c);}
2.
public static void main(String[] args) {// 1. 键盘录入一个字符串Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str = sc.next();//2.统计---计数器思想//定义三个计数器int bigCount = 0;int smallCount = 0;int numberCount = 0;for (int i = 0; i < str.length(); i++) {//i 依次表示字符串中的每一个索引char c = str.charAt(i);if(c>='a'&&c<='z'){//char类型的变量在参与计算的时候自动类型提升为int查询ascii码表smallCount++;}else if(c>='A'&&c<='Z'){bigCount++;}else if(c>='0'&&c<='9'){numberCount++;}}System.out.println("小写字母有:"+smallCount+"个");System.out.println("大写字母有:"+bigCount+"个");System.out.println("数字字母有:"+numberCount+"个");}
3.3.3 练习三:字符串拼接和反转
public static void main(String[] args) {//1.我要干嘛?---遍历数组并把数组拼接成一个字符串//2.我干这件事情需要什么才能完成?---数组//3.我干完了是否要把结果返回给调用处---返回一个拼接之后的字符串// 如果调用处需要继续使用,那么必须返回//如果调用处不需要继续使用,那么可以返回也可以不返回int[] arr={1,2,3};String str = arrToString(arr);System.out.println(str);//123}public static String arrToString(int[] arr){if(arr==null){return"";}if(arr.length==0){return "[]";}String result = "[";//当代码执行到这里表示什么?//表示数组不是null,也不是长度为0的for (int i = 0; i < arr.length; i++) {if(i==arr.length-1){result = result+arr[i];}else{result = result+arr[i]+",";}}//此时拼接右括号result = result + "]";return result;}
2.
public class ArithmeticoperatorDemo1 {public static void main(String[] args) {String result = reverser("cnm");System.out.println(result);}public static String reverser(String str){String result = "";for (int i = str.length()-1; i >=0; i--) {char c = str.charAt(i);result += c;}return result;}
}
3.3.4 练习四
3.3.5 练习五
3.4 StringBuilder
使用StringBuilder的场景:
- 1.字符串的拼接
- 2.字符串的反转
相当于一个字符串的工具,StringBuilder不是字符串类型!!!!
3.4.1 StringBuilder构造方法
3.4.2 StringBuilder常用方法
1.append 添加方法
public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder();//打印//普及://因为stringBuilder是Java已经写好的类// java在底层对他做了一些特殊处理。//打印对象不是地址值而是属性值。System.out.println(sb);}
所以它没有返回一个地址值
public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加元素sb.append(1);sb.append(2.3);sb.append(true);System.out.println(sb);}
2.reverse 反转方法
sb.reverse();
3.length 获取长度方法
int len = sb.length();System.out.println(len);
4.toString
public static void main(String[] args) {//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加字符串sb.append("aaa");sb.append("wwww");sb.append("xxxx");System.out.println(sb);//abcaaawwwwxxxx只是在一个容器里面//3.再把StringBuilder变回字符串类型String str = sb.toString();System.out.println(str);//现在的abcaaawwwwxxxx才是字符串类型}
3.4.3 链式编程
当我们在调用一个方法的时候,不需要用变量接收他的结果,可以继续调用其他方法
1.
public static void main(String[] args) {String len = getString().substring(1).replace('b','w');System.out.println(len);int len2 = len.length();System.out.println(len2);}public static String getString(){Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str = sc.next();return str;}
2.
将上方3.4.2内容的第4点:
sb.append("aaa");sb.append("wwww");sb.append("xxxx");
可写成->一条链子,效果相同
sb.append("aaa").append("wwww").append("xxxx");
练习:
1.
equals() 方法用于比较两个字符串的内容是否相等。
package com.itheima.demo1;import java.util.Scanner;public class ArithmeticoperatorDemo1 {public static void main(String[] args) {// 1.键盘录入字符串Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串:");String str = sc.next();//2.反转键盘录入的字符串String result = new StringBuilder().append(str).reverse().toString();//.3比较if(str.equals(result)){System.out.println("当前字符串是对称字符串");}else{System.out.println("当前字符串不是对称字符串");}}
}
2.
package com.itheima.demo1;public class ArithmeticoperatorDemo1 {public static void main(String[] args) {//1.定义数组int[] arr = {1, 2, 3, 4};//2.定义一个接受字符数组的子函数,把arr放进去String str = arrString(arr);System.out.println(str);}public static String arrString(int[] arr) {//3. new一个StringBuilder容器,用来存放字符串StringBuilder sb = new StringBuilder();sb.append("[");//将 [ 先加入到容器中//4.循环遍历分割数组for (int i = 0; i < arr.length; i++) {//5.采用判断语句,如果加入到了最后一个字时,就i=length-1,才会不打印 , 逗号//其他加入的时候,就带 ,逗号一加入进容器if (i == arr.length - 1) {sb.append(arr[i]);} else {sb.append(arr[i]).append(",");}}//循环结束之后,填右边括号sb.append("]");//6.完成后返回sb的字符串类型return sb.toString();}
}
3.4.4 StringJoiner
对于有时候StringBuilder按照数组拼接字符串的时候就比较麻烦了,中间有的时候拼,有的时候不拼
StringJoiner概述:
StringJoiner对象的创建
StringJoiner的成员方法
1.add() 添加内容
delimiter:中间间隔的符号,prefix:开始的符合,suffix:结尾的符号
public static void main(String[] args) {StringJoiner sj = new StringJoiner("-----");//2.添加元素sj.add("aaa").add("bbbb").add("ccc");//3.打印结果System.out.println(sj);}
2.
public static void main(String[] args) {StringJoiner sj = new StringJoiner(",","[","]");//2.添加元素sj.add("aaa").add("bbbb").add("ccc");int len = sj.length();System.out.println(len);//14//3.打印结果System.out.println(sj);//容器的类型String str = sj.toString();System.out.println(str);//字符串的类型}
总结:
3.4.5 字符串原理
扩展底层原理1和2:字符串原理
扩展底层原理3:字符串拼接的底层原理
1.当等号的右边没有变量时:
在编译的时候,就会将"a"+ “b” +“c"拼接为"abc”
2.当等号的右边有变量时:
-
在jdk8以前:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。
拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。 -
在jdk8之后:在编译时,会先预估字符串的长度并创建一个数组,再把数组变成一个字符串,这样就消耗性能了。
面试练习题:
2.
那就采用StringBuilder 和StringJoiner 进行优化
扩展底层原理5:StringBuilder提高效率原理
stringBuilder是一个内容可变的容器,所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
3、4原理小结:
扩展底层原理5:StringBuilder源码分析
总结:
ctrl + n IDEA快捷键 出现搜索界面
在所有位置里寻找,搜索界面默认在当前项目文件里找不到
--------->
ctrl + f12 ---->寻找toString
3.4.6 字符串综合练习
2.
3.
4. 集合
集合是一个容器,可以用来存储数据,和数组不同的是,集合的长度可以发生变化。当添加元素时,会自动扩容。
- 集合可以存储引用数据类型,不能直接存储基本数据类型,要把基本数据类型变成其对应的包装类才能存储。
4.1 ArrayList 集合(之一)
ArrayList集合的创建:
public static void main(String[] args) {//1.创建集合的对象//泛型:指限定集合中存储数据的类型,就是 <里面的>//ArrayList<String> list = new ArrayList<String>();// jDK7之后:ArrayList<String> list = new ArrayList<>();System.out.println(list);//此时我们创建的是ArrayList的对象,//这个类在底层做了一些处理//打印对象不是地址值,而是集合中存储数据内容 也就是[]//在展示的时候会拿[]把所有的数据进行包裹}
ArrayList成员方法
- add()和remove的返回值都是布尔值,add默认返回true,不用管,而remove在删除成功时返回true,失败时返回false
同时,remove还可以根据索引进行删除,返回值是被删除的元素 - set是修改指定索引上的值,返回被覆盖的值。
- get就是获取相应索引的元素
- size就是集合的长度,类似于length
public static void main(String[] args) {//1.创建集合的对象ArrayList<String> list = new ArrayList<>();//2.添加元素list.add("aaa");list.add("aaa");list.add("www");list.add("ddd");System.out.println("2:"+list);//3.删除元素boolean result1 = list.remove("aaa");System.out.println("3:"+result1);//当要删除的元素不存在时,就会falseSystem.out.println("3:"+list);//把被删除的元素进行返回String str = list.remove(2);System.out.println("3:"+str);System.out.println("3:"+list);//4.修改元素String res = list.set(1, "cccc");//把替换的元素进行返回System.out.println("4:"+res);System.out.println("4:"+list);//5.查询元素String s = list.get(0);System.out.println("5:"+s);System.out.println("5:"+list);//6.遍历元素 list.forifor (int i = 0; i < list.size(); i++) {//list.get(i) 元素String s1 = list.get(i);System.out.println("6:"+s1);System.out.println("6:"+list);}}
4.2 集合综合练习
4.2.1 添加字符串和整数遍历
public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");list.add("ddd");//遍历System.out.print("[");for (int i = 0; i < list.size(); i++) {if(i==list.size()-1){System.out.print(list.get(i));}else{System.out.print(list.get(i)+",");}}System.out.println("]");}
2.
下方遍历代码一样,中间改变
ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
添加字符类型遍历也是同理
ArrayList<Character> list = new ArrayList<>();list.add('a');list.add('b');list.add('c');list.add('d');
4.2.2 基本数据类型的包装类
这里的包装类实际上就是泛型里的关键字
jdk5以后int Intleger 之间是可以互相转化的
4.2.3 添加学生对象并遍历
public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>();//2.创建学生对象Student s1 = new Student("zhangsan",23);Student s2 = new Student("magua",24);Student s3 = new Student("xiaolaoban",25);//3.添加元素list.add(s1);list.add(s2);list.add(s3);//4.遍历集合for (int i = 0; i < list.size(); i++) {Student stu = list.get(i);System.out.println(stu.getName()+","+stu.getAge());}}
2.
遍历思路:
public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>();// 长度为0//2.键盘录入学生的信息并添加到集合当中Scanner sc = new Scanner(System.in);for (int i = 0; i < 3; i++) {Student s = new Student();System.out.println("请输入学生的姓名:");String name = sc.next();System.out.println("请输入学生的年龄:");int age = sc.nextInt();//把name和age赋值给学生对象s.setName(name);s.setAge(age);//把学生对象添加到集合当中list.add(s);}//集合里面是否有学生对象//有? 没有?System.out.println(list.size());//3for (int i = 0; i < list.size(); i++) {Student stu = list.get(i);System.out.println(stu.getName()+","+stu.getAge());}}
4.2.4 添加用户对象并判断是否存在
javabean部分:
package test10;public class User {private String id;private String username;private String password;public User() {}public User(String id, String username, String password) {this.id = id;this.username = username;this.password = password;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
Test部分:
package test10;import java.util.ArrayList;public class test {public static void main(String[] args) {//1.创建集合ArrayList<User> list = new ArrayList<>();//2.创建三个用户对象User u1 = new User("magua001","zhangsan","12345");User u2 = new User("magua002","lisi","12345678");User u3 = new User("magua003","wangwu","12345asd");//3.把用户对象添加到集合当中list.add(u1);list.add(u2);list.add(u3);//4.调用方法查看id是否存在boolean flag = contains(list, "magua001");System.out.println(flag);}public static boolean contains(ArrayList<User> list,String id){
// for (int i = 0; i < list.size(); i++) {
// User u = list.get(i);
// String uid = u.getId();
// if(uid.equals(id)){
// //如果找到了直接返回true
// return true;
// }
// }
// //当循环结束表示集合里面所有的元素都比较完毕还没有一样的
// //那么就返回false
// return false;return getIndex(list,id)>=0;}public static int getIndex(ArrayList<User>list,String id){for (int i = 0; i < list.size(); i++) {User u = list.get(i);String uid = u.getId();if(uid.equals(id)){return i;}}return -1;}
}
4.2.5 添加手机对象并返回要求的数据
phone的javabean:
package test11;public class Phone {private String brand;private int price;public Phone() {}public Phone(String brand, int price) {this.brand = brand;this.price = price;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}
}
test部分:
public static void main(String[] args) {//1.创建集合ArrayList<Phone> list = new ArrayList<>();//2.创建三个用户对象Phone p1 = new Phone("xiaomi",1000);Phone p2 = new Phone("iphone",4000);Phone p3 = new Phone("cuizi",2000);//3.把用户对象添加到集合当中list.add(p1);list.add(p2);list.add(p3);//4.调用方法ArrayList<Phone> phoneInfoList = getPhoneInfo(list);//5.遍历集合for (int i = 0; i < phoneInfoList.size(); i++) {Phone phone = phoneInfoList.get(i);System.out.println(phone.getBrand()+","+phone.getPrice());}}//1.我要干嘛?查询手机信息//2.我干这件事情,需要什么才能完成?集合//3.我干完了,方法的调用处是否需要继续使用结果?返回//技巧://如果我们要返回多个数据,可以把这些数据先放到一个容器当中,再把容器返回/集合数组public static ArrayList<Phone> getPhoneInfo(ArrayList<Phone> list){//定义一个集合用于存储价格低于3000的手机对象ArrayList<Phone> resultList = new ArrayList<>();//遍历集合for (int i = 0; i < list.size(); i++) {Phone p = list.get(i);int price = p.getPrice();//如果当前手机的价格低于3000,if(price<3000){resultList.add(p);}}return resultList;//返回的是集合,函数的返回值类型就得是集合}
5. 学生管理系统
学会阅读需求文档,在了解需求文档后,自己画出需求的结构流程图(业务流程图)
流程图:
Ctrl + alt + t 全选中内容后,快捷生成结构环绕方式
StudentTest第一部分:
package test1;import java.util.ArrayList;
import java.util.Scanner;public class StudentTest {public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>();while (true) {//不要把ArrayList<Student> list = new ArrayList<>();//放在循环内部,这样在添加学生到list后,再循环一次,list又变成了0,这样查询的时候就总是无法查到System.out.println("----------------欢迎来到小黑子的学生管理系统----------------");System.out.println("1:添加学生");System.out.println("2:删除学生");System.out.println("3:修改学生");System.out.println("4:查询学生");System.out.println("5:退出");System.out.println("请输入您的选择:");Scanner sc = new Scanner(System.in);//定义一个字符串来接收String choose = sc.next();switch (choose) {case "1" -> addStudnet(list);case "2" -> deleteStudnet(list);case "3" -> updateStudnet(list);case "4" -> queryStudnet(list);case "5" -> {System.out.println("退出");System.exit(0);//停止虚拟机运行}default -> System.out.println("没有这个选项");}}}//添加学生public static void addStudnet(ArrayList<Student> list) {//利用空参构造先创建学生对象Student s = new Student();Scanner sc = new Scanner(System.in);String id = null;while (true) {System.out.println("请输入学生的id:");id = sc.next();boolean flag = contains(list, id);if (flag) {//true 表示id已经存在,需要重新录入System.out.println("id已经存在,请重新录入");} else {//表示id不存在,唯一s.setId(id);break;}}System.out.println("请输入学生的姓名:");String name = sc.next();s.setName(name);System.out.println("请输入学生的年龄:");int age = sc.nextInt();s.setAge(age);System.out.println("请输入学生的家庭住址:");String address = sc.next();s.setAddress(address);//把学生对象添加到集合当中list.add(s);//提示用户System.out.println("学生信息添加成功");System.out.println(list.size());}//删除学生public static void deleteStudnet(ArrayList<Student> list) {Scanner sc = new Scanner(System.in);System.out.println("请输入要删除的id:");String id = sc.next();//查询id在集合中的索引int index = getIndex(list, id);//对index进行判断//如果-1,就表示索引不存在,结束方法,返回初始菜单if (index >= 0) {//如果大于等于0的,表示存在,直接删除list.remove(index);System.out.println("id为:" + id + "的学生删除成功");} else {System.out.println("id不存在,删除失败");}}//修改学生public static void updateStudnet(ArrayList<Student> list) {Scanner sc = new Scanner(System.in);System.out.println("请输入要修改学生的id:");String id = sc.next();int index = getIndex(list,id);if(index == -1){System.out.println("要修改的id:"+id+"不存在,请重新输入");return;}//当代码执行到这里,表示什么?表示当前id是存在的//获取要修改的学生对象Student stu = list.get(index);//输入其他的信息并修改System.out.println("请输入修改的学生姓名:");String newName = sc.next();stu.setName(newName);System.out.println("情输入修改的学生年龄:");String newAge = sc.next();stu.setName(newAge);System.out.println("情输入修改的学生家庭住址:");String newAddress = sc.next();stu.setName(newAddress);System.out.println("学生信息修改完成");}//查询学生public static void queryStudnet(ArrayList<Student> list) {System.out.println(list.size());if (list.size() == 0) {System.out.println("当前无学生信息,请添加后再查询");return;}//打印表头信息System.out.println("id\\t\\t姓名\\t年龄\\t家庭住址");//当代码执行到这里时表示集合是有数据的,遍历集合的每个数据for (int i = 0; i < list.size(); i++) {Student stu = list.get(i);System.out.println(stu.getId() + "\\t" + stu.getName() + "\\t" + stu.getAge() + "\\t" + stu.getAddress());}}//判断id 的方法public static boolean contains(ArrayList<Student> list, String id) {
// //循环遍历每一个学生对象
// for (int i = 0; i < list.size(); i++) {
// //拿到学生对象后,获取id并进行判断
// Student stu = list.get(i);
// String sid = stu.getId();
// if(sid.equals(id)){
// //存在,true
// return true;
// }
// }
// //不存在方法就返回false
// return false;return getIndex(list, id) >= 0;}//通过id获取索引的方法public static int getIndex(ArrayList<Student> list, String id) {//遍历集合for (int i = 0; i < list.size(); i++) {//得到每一个学生对象Student stu = list.get(i);//得到每一个学生对象的idString sid = stu.getId();//拿着集合中的学生id跟要查询的id进行比较if (sid.equals(id)) {//如果一样,那么就返回索引return i;}}return -1;}
}
swich语句不能用箭头表达式,java版本换成jdk17以上行了。
5.1 学生管理系统升级版
需求图:
流程图:
1.注册
2.登录
3.忘记密码
6. 面向对象进阶
6.1 static
6.1.1 static-静态变量
static(静态变量)(静态变量被该类所有对象共享),是Java中的一个修饰符,可以修饰成员方法,成员变量
javabean类:
public class Student {private String name;private int age;private String gender;public static String teacherName;public Student() {}public Student(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}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 getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}//行为public void study(){System.out.println(name+"正在学习");}public void show(){System.out.println(name+","+age+","+gender+","+teacherName);}
测试类:
public static void main(String[] args) {//1.创建学生对象Student s1 = new Student();s1.setName("张三");s1.setAge(23);s1.setGender("man");s1.teacherName = "麻瓜";s1.study();s1.show();//2.创建第二个学生对象Student s2 = new Student();s2.setName("李四");s2.setAge(25);s2.setGender("man");s2.study();s2.show();}
当这里的teacherName被赋值后,static会被Student类里所有对象共享(公共的一个属性)
静态变量是随着类的加载而加载的,优先于对象出现,被赋值是单独存储再堆内存中的静态区域
示意图:
静态区里的变量是对象共享的,在内存中只有一份,谁用谁拿,非静态的变量是每一个对象所独有的,每一个对象里的非静态的变量都是单独存放的。
判断一个变量是否是静态变量,主要就是两个字,共享
需要共享的变量就是静态变量
6.1.2 static-静态方法和工具
静态方法
工具类
工具类:帮助我们做一些事情的,但是不描述任何事物的类
目前一共学习了三种类
工具类的要求:
这里的第2个私有化构造方法
就是
public class Student {private public Student() {}
}
一个类一旦被私有化构造方法后,就不能创建这个类的对象了。
练习:
1.
javabean类:
public class ArrayUtil {//私有化构造方法//目的:为了不让外界创建他的对象private ArrayUtil(){}public static String printArr(int[] arr){//一到字符串的拼接,就一定要想到StringBuildeStringBuilder sb = new StringBuilder();sb.append("[");for (int i = 0; i < arr.length; i++) {if(i==arr.length-1){sb.append(arr[i]);}else{sb.append(arr[i]).append(", ");}}sb.append("]");return sb.toString();}public static double getAverage(double[] arr){double sum =0;for (int i = 0; i < arr.length; i++) {sum = sum + arr[i];}return sum/arr.length;}
}
测试类:
public class TestDemo {public static void main(String[] args) {//测试工具类的两个方法是否正确int[] arr1 = {1, 2, 3, 4, 5};String str = ArrayUtil.printArr(arr1);System.out.println(str);double[] arr2 ={1.5,23.43,654.43,1.23,23.3};double avg = ArrayUtil.getAverage(arr2);System.out.println(avg);}
}
2.
工具类:
import java.util.ArrayList;public class StudentUtil {private StudentUtil(){}//静态方法public static int getMaxAgeStudent(ArrayList<Student> list){//1.定义一个参照物int max = list.get(0).getAge();//2.循环遍历集合for (int i = 0; i < list.size(); i++) {//i 索引 list.get(i)元素/学生对象 我们还需要getAge获取到年龄之后再进行比较int tempAge = list.get(i).getAge();if(tempAge>max){max = tempAge;}}//3.直接返回return max;}
}
Test部分调用工具类方法:
//4.调用工具类方法int maxAgeStudent = StudentUtil.getMaxAgeStudent(list);System.out.println(maxAgeStudent);
6.1.3 static-注意事项
在非静态方法中,有一个隐藏的this,这个this就表示当前方法调用者的地址值
在第一次调用show()方法时,虚拟机就会把第一次调用者的地址赋值给方法中的this,就像图中所示
第二次同理,虚拟机会把第二次调用者的地址赋值给方法中的this
this的值
this的这一特性就是区分不同对象的 即在调用成员变量时,变量前面有隐含的this,从而显示出不同变量的结果
上面sout里的this可以省略
- 而在static静态方法中,是没有这个this关键字的
- 原因就是静态方法是公用的,而this一般是独立的对象进行使用,不符合公用的理念。
示意图:
- 静态方法不能访问非静态成员变量(也就是实例变量即对象)
因为在使用静态方法时,通过类名调用会直接到静态存储位置去找变量,而非静态的变量是随着对象的创建而创建的,在静态存储位置找不到,所以静态方法不能调用非静态成员变量
- 静态方法不能访问非静态的成员方法
因为非静态的方法需要调用者,而在静态方法中是没有this的,也就没有调用者,自然就不能使用了
综上,静态方法只能调用静态的内容
- 非静态方法可以访问所有
因为静态的是公用的,所以非静态既可以访问到静态,也可以访问非静态
小结:
6.1.4 重新认识main方法
JVM:虚拟机
例子:
点击IDEA右上角的锤子旁边的按钮
在程序参数里填写,args即可返回值
6.2 继承
6.2.1 封装
封装:
对象代表什么,就得封装对应的数据,并提供数据对应的行为
像这种相同的行为太多了,这时候就需要用到封装
封装完行为方法之后,就要用到继承了
6.2.2 继承的描述
继承实际上就是类跟类之间的父子关系
什么时候用继承?
小结:
继承需要学习的点:
6.2.3 继承的特点
即儿子继承父亲,父亲继承爷爷
即子类的父类是直接父类,父类的父类是子类的间接父类
java中有一个祖宗类就是Object,每一个类都直接或间接继承于Object
小结:
练习:
设计继承体系时,尽量先搞清楚体系逻辑,画一张图,从子类到父类
设计的核心就是:共性的内容抽取,子类是父类的一种
书写代码时,从父类到子类
小结:
6.2.4 子类继承父类的特性
-
构造方法:不论私有(private)还是非私有(像public等)的构造方法,子类都是不能继承的
例子:
-
成员变量:不论私有(private,不能直接调用)还是非私有(像public等)的成员变量,子类都是可以继承的(相当于从父类哪里copy了一份过来)
1.没有用private修饰的继承成员变量的内存图:
2.有用private修饰的继承成员变量的内存图:
- 这里new出来一个子类后,会把堆内存中开辟出来的空间分为两部分,第一部分是继承父类的成员变量,第二类是子类自己的成员变量
- 如果父类的成员变量使用private修饰后,子类对象在堆内存中就无法使用继承父类的成员变量。
父类会把非private,非static和非final的方法(这些方法统称为虚方法)抽取出来,放到虚方法表里,在继承的时候,父类会把虚方法表交给子类复制,子类可以添加新的虚方法加入到子类的虚方法表中,使后代继续复制
- 成员方法:非私有的成员方法(虚方法)可以被继承,私有的成员方法就不能被继承下来
运行效率低下:
以下如此可以大大提高性能:
例子:
6.2.5 终端的jps和jhsdb hsdb
在终端中输入jps,得到类中获得的id
输入jhsdb hsdb 打开HotSpot Debugger
- (HSDB(Hotspot Debugger) ,是一款内置于 SA 中的 GUI 调试工具,可用于调试 JVM运行时数据,从而进行故障排除。)
在file中寻找到第一个点击进入
从jps中获得的id输入,ok
之后显示
在tools里找到Memory Viewer
在tools里找到Inspector