Java-基础篇【面向对象基础、String、集合】
1:设计类
2:定义类的注意事项
package com.itheima.createobject; public class Car { // 属性(成员变量) String name; // 名称 double price; // 价格 // 行为(方法) public void start(){ System.out.println(name + " 价格是:" + price +", 启动成功!"); } public void run(){ System.out.println(name + " 价格是:" + price +", 跑的很快!"); } }
package com.itheima.createobject; /** 目标:学习定义类的一些注意事项。 成员变量修饰符暂时不写 实际开发中一个代码文件不建议定义多个类:分开定义 */ public class Student { // 修饰符 数据类型 变量名称 = 初始化值; String name; // 修饰符暂时不写,初始值暂时不给 double height; } class Animal{ // 不能public修饰 } class Cat{ }
package com.itheima.createobject; /** 目标:掌握自己设计类,并获得对象 类名 对象名 = new 类名() */ public class Test { public static void main(String[] args) { // 如何去获取汽车的对象。 Car c1 = new Car(); System.out.println(c1); c1.name = "宝马X3"; c1.price = 37.89; System.out.println(c1.name); System.out.println(c1.price); c1.start(); c1.run(); System.out.println("-------------------"); Car c2 = new Car(); c2.name = "奔驰GLC"; c2.price = 39.89; System.out.println(c2.name); System.out.println(c2.price); c2.start(); c2.run(); } }
package com.itheima.createobject; public class Test2 { public static void main(String[] args) { Student s1 = new Student(); // 创建学生对象 System.out.println(s1.name); // 整数默认值:0 double类型默认值:0.0 引用数据类型默认值:null System.out.println(s1.height); Student s2 = new Student(); System.out.println(s2.name); System.out.println(s2.height); } }
package com.itheima.createobject; public class test_ywt { public static void main(String[] args) { System.out.printf("hello"); } public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
3:成员变量默认值
4:多个对象的内存图
1:对象到底是放在哪个位置的? 堆内存中 2: Car c = new Car(); c变量名中存储的是什么? 存储的是对象在堆内存中的地址。 3: 成员变量(name、price)的数据放在哪里,存在于哪个位置? 对象中,存在于堆内存中。
package com.itheima.memory; public class Student { String name; char sex; String hobby; public void study(){ System.out.println("姓名:" + name +",性别是:" + sex + ",爱好是:" + hobby + "的学生在好好学习,天天向上!"); } }
package com.itheima.memory; /** 对象内存图 方法都是加载到栈里运行的,运行完了再退出去 1:Test.class 和 Car.class 文件的 代码方法和类加载到 方法区域 2:main函数加载到栈内存 运行 3:栈内存生成 s1这个 引用类型变量【对象变量】 4:new Student()在堆内存分配一块区域,对象区域,对象分配对象的属性空间name和price【成员变量空间】 一开始默认数据NULL和0 存储对象的行为方法 方法不会之间加载到堆内存区域,因为浪费空间,方法直接放在 class文件加载的方法区就行,堆内存中存在一份 对象能够找到方法,说明堆内存里还是存储一个 成员方法引用地址 ,指向方法区的地址以便能够调用 对象也有一个在堆内存地址,赋值给栈内存里 s1这个变量指向,s1指向这个对象 5:s1变量存储的对象地址找到对象,去操作对象里的属性和方法【赋值 打印】 6:s1.study() s1找到 对象,然后根据 对象里 方法引用地址 找到方法区域的 study这个方法 study方法加载到栈里运行,s1调用的study方法,方法再访问s1相应的内部的成员变量执行 study方法 对象是存储在堆内存里的,成员变量也是存储在对象里的 s1 和 s2这些对象变量 存储的是对象在堆内存中的地址 两个变量指向同一个对象内存图: 垃圾回收: 注意:当堆内存中的对象【类对象,数组对象】,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾” 下面的代码:有一个学生对象 由 s1 和s2指向, s1=null取消指向 s2=null也取消指向,指向学生对象的两条线都掐断,这样内存中的学生对象变成垃圾对象,会被java垃圾回收机制定期清除【自动清除】 */ public class Test { public static void main(String[] args) { // 目标:掌握2个变量指向同一个对象的形式 Student s1 = new Student(); s1.name = "小明"; s1.sex = '男'; s1.hobby = "睡觉、游戏、听课"; s1.study(); // 关键:把s1赋值给学生类型的变量s2 Student s2 = s1; // s1 和 s2指向同一个变量 System.out.println(s1); System.out.println(s2); s2.hobby = "爱提问"; System.out.println(s2.name); System.out.println(s2.sex); System.out.println(s1.hobby); s2.study(); // s1 = null; // s2 = null; // System.out.println(s1.name); } }
5:两个变量指向同一个对象内存解析
6:垃圾回收机制
垃圾回收:
注意:当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”。
7:面向对象之——构造器
package com.itheima.constructor; public class Car { String name; double price; public Car(){ // 无参数构造器(默认存在的) System.out.println("无参数构造器被触发执行~~~"); } public Car(String n, double p){ // 有参数构造器 System.out.println("有参数构造器被触发执行~~~"); name = n; // 当前成员变量的name 赋值成 外面类实例化传参过来的参数 n price = p; } }
package com.itheima.constructor; /** 目标:明白构造器的作用和分类。(开发的人,理解能力好) */ public class ConstructorDemo { public static void main(String[] args) { Car c = new Car(); // 调用无参数构造器(默认存在的) // c.name = ""; // c.price System.out.println(c.name); // 访问属性使用的默认值 System.out.println(c.price); // 访问属性使用的默认值 Car c2 = new Car("奔驰GLC", 39.78); // 调用有参数构造器 System.out.println(c2.name); System.out.println(c2.price); } }
8:this关键字
package com.itheima.thisdemo; public class Car { String name; double price; public void goWith(String name){ System.out.println(this.name +"正在和:" + name +"比赛!"); } public Car(){ // 无参数构造器(默认存在的) System.out.println("无参数构造器被触发执行~~~"); } // public Car(String name, double price){ // name = name; // price = price; // // 这样写不可以,name=name,等号前面的name访问传参name,等号后面的name还是访问的传参name,
//不会修改对象变量String name【自己值给自己赋值】【没有给当前成员变量赋值,采用 this】 // } // public Car(String a, double b){ // name = a; // price = b; // // 这样写才可以赋值,采用不同的变量名字,标准还是使用this // } public Car(String name, double price){ // 有参数构造器 System.out.println("有参数构造器被触发执行~~~"); System.out.println(this); this.name = name; // name赋值给当前对象成员变量的name this.price = price; // price赋值给当前对象成员变量的price } }
package com.itheima.thisdemo; /** 目标:说出this关键字的作用,并学会其使用。 */ public class ThisDemo { public static void main(String[] args) { Car c = new Car("宝马X3", 37.89); System.out.println(c); System.out.println(c.name); System.out.println(c.price); c.goWith("奔驰GLC"); } }
9:封装
10:封装的常见手段 private关键字的使用
package com.itheima.encapsulation; public class Student { // private私有的成员变量,只能在本类访问。 private int age; public int getAge(){ return age; } public void setAge(int age){ if(age >= 0 && age <= 200){ this.age = age; }else { System.out.println("年龄数据有问题,应该不是人的年龄!"); } } }
package com.itheima.encapsulation; /** 目标:学会面向对象的三大特征:封装的形式、作用。 */ public class Test { public static void main(String[] args) { Student s = new Student(); // s.age = -23; s.setAge(-23); System.out.println(s.getAge()); } }
11:JavaBean标准编程
package com.itheima.javabean; public class User { private double height; // 1:成员变量私有化,使用 private修饰 private String name; private double salary; private String address; private String phone; public User() { // 3:无参数构造器,默认自带的 // 鼠标右键——>Generate——>Construct——>select None一个都不选——>点击ok自动生成无参数构造器 } public User(double height, String name, double salary, String address, String phone) { // 有参数构造器 // 鼠标右键——>Generate——>Construct——>shift全选所有的private私有成员变量——>点击ok自动生成有参数构造器 this.height = height; this.name = name; this.salary = salary; this.address = address; this.phone = phone; } // 2:提供成员变量的 set get方法 // 鼠标右键——>Generate——>Getter and Setter——>shift全选所有的private私有成员变量——>点击ok自动生成Getter and Setter方法 // 自动生成的 方法没有安全校验的,比如身高需要 1-2米,这里面没有校验 public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
package com.itheima.javabean; /** JavaBean 也可以称为实体类【现实生活中有个体的】,其对象可以用于在程序中封装数据 学生类,汽车类,用户类:实体类 测试类不是:非实体类 new 一个学生对象就可以封装学生的数据 标准JavaBean【实体类】须满足如下书写要求 成员变量使用 private 修饰。 提供成员变量对应的 setXxx() / getXxx()方法。 必须提供一个无参构造器;有参数构造器是可写可不写的 满足这 3 个要求就可以认为是一个标准的 JavaBean【java实体类】 */ public class Test { public static void main(String[] args) { User user = new User(); // 无参数构造器 user.setName("二狗"); user.setHeight(163); user.setSalary(50000); user.setAddress("中国"); user.setPhone("13141314520"); // String name = user.getName(); // System.out.println(name); System.out.println(user.getName()); System.out.println(user.getHeight()); System.out.println(user.getSalary()); System.out.println(user.getAddress()); System.out.println(user.getPhone()); System.out.println("--------------------"); User user1 = new User(176, "黑马吴彦祖", 30000, "黑马", "110"); // 有 // 参数构造器 System.out.println(user1.getName()); System.out.println(user1.getHeight()); System.out.println(user1.getSalary()); System.out.println(user1.getAddress()); System.out.println(user1.getPhone()); } }
package com.itheima.javabean2; /** private String name; 私有成员变量,外部无法通过对象 a.name 访问了。只能通过 getName 方法访问 */ public class Article { // 商品对象 private String name; // 名称 private double price; // 价格 private int buyNumber; // 购买数量 public Article() { } public Article(int id, String name, double price, int buyNumber) { this.name = name; this.price = price; this.buyNumber = buyNumber; } 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 getBuyNumber() { return buyNumber; } public void setBuyNumber(int buyNumber) { this.buyNumber = buyNumber; } }
package com.itheima.javabean2; import java.util.Scanner; public class Test { public static void main(String[] args) { Article[] shopCar = new Article[10]; // a、定义一个数组存储商品对象的,代表购物车对象。 // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null // b、让用户选择功能 while (true) { Scanner sc = new Scanner(System.in); System.out.println("添加商品:add"); System.out.println("查看商品:query"); System.out.println("修改数量:update"); System.out.println("结算价格:pay"); System.out.println("请您选择要操作的功能:"); String command = sc.next(); switch (command) { case "add": addArticle(shopCar); // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品 alt + 回车 :快捷生成方法 break; case "query": queryArticle(shopCar); // 查看购物车中的商品信息 break; case "update": updateArticle(shopCar); // 修改商品的购买数量 break; case "pay": calcPayMoney(shopCar); // 查结算金额 break; default: // 输入命令有问题走这个 System.out.println("当前命令输入有误!"); } String q = "QQ"; System.out.println(command == q ); // if(command == "Q"){ // System.out.println("等于啊"); // } if(command.equals("Q")){ break; } } } private static void calcPayMoney(Article[] shopCar) { queryArticle(shopCar); double money = 0; // 准备一个double类型的变量统计总金额 for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; if(a != null){ money += (a.getPrice() * a.getBuyNumber()); }else { break; } } System.out.println("本次商品购买的总价为:" + money); } public static void updateArticle(Article[] shopCar) { Scanner sc = new Scanner(System.in); while (true) { System.out.println("请您输入要修改数量的商品名称:"); String name = sc.next(); Article a = getArticleByName(name , shopCar ); // 返回根据商品名称找到的商品对象,也可能返回null if(a != null){ // 找到了商品对象 System.out.println("请您输入修改后购买的数量:"); int buyNumber = sc.nextInt(); a.setBuyNumber(buyNumber); // 更新修改数量 System.out.println("该商品的购买数量修改了!"); break; // 商品修改完成break }else { // 没有找到商品对象,继续输入,找到为止 System.out.println("购物车中没有该商品信息"); } } } public static Article getArticleByName(String name , Article[] shopCar){ // 查根据名字返回商品对象:Article for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; // 商品不为null if(a != null && a.getName().equals(name) ){ return a; } } return null; } public static void queryArticle(Article[] shopCar) { System.out.println("============查询购物车信息=========================="); System.out.println("商品名称\t商品价格\t商品的购买数量"); // 展示购物车的商品信息 for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址 if(a != null){ // 不为null 说明有数据可以展示商品对象 System.out.println(a.getName() +"\t" + a.getPrice() + "\t" + a.getBuyNumber()); }else { // 为null说明循环遍历结束了 return; // break; 也可以 } } } public static void addArticle(Article[] shopCar) { // 参数接受一个商品数组购物车 Scanner sc = new Scanner(System.in); // 1:录入用户输入的商品信息 System.out.println("请您输入商品的名称:"); String name = sc.next(); System.out.println("请您输入商品的价格:"); double price = sc.nextDouble(); System.out.println("请您输入购买商品的数量:"); int buyNumber = sc.nextInt(); Article a = new Article(); a.setName(name); a.setPrice(price); a.setBuyNumber(buyNumber); for (int i = 0; i < shopCar.length; i++) { if(shopCar[i] == null){ shopCar[i] = a; break; } } System.out.println("添加成功!"); } }
//package com.itheima.javabean2; // //import java.util.Scanner; // //public class TestArticle { // public static void main(String[] args) { // Article[] shopCar = new Article[10]; // a、定义一个数组存储商品对象的,代表购物车对象。 // // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null // // b、让用户选择功能 // while (true) { // Scanner sc = new Scanner(System.in); // System.out.println("添加商品:add"); // System.out.println("查看商品:query"); // System.out.println("修改数量:update"); // System.out.println("结算价格:pay"); // System.out.println("请您选择要操作的功能:"); // String command = sc.next(); // switch (command) { // case "add": // addArticle(shopCar); // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品 alt + 回车 :快捷生成方法 // break; // case "query": // queryArticle(shopCar); // 查看购物车中的商品信息 // break; // case "update": // updateArticle(shopCar); // 修改商品的购买数量 // break; // case "pay": // calcPayMoney(shopCar); // 查结算金额 // break; // case "Q": // break; // default: // 输入命令有问题走这个 // System.out.println("当前命令输入有误!"); // } // break; // } // } // // private static void calcPayMoney(com.itheima.demo.Article[] shopCar) { // queryArticle(shopCar); // double money = 0; // 准备一个double类型的变量统计总金额 // for (int i = 0; i < shopCar.length; i++) { // com.itheima.demo.Article a = shopCar[i]; // if(a != null){ // money += (a.price * a.buyNumber); // }else { // break; // } // } // System.out.println("本次商品购买的总价为:" + money); // } // // public static void updateArticle(com.itheima.demo.Article[] shopCar) { // Scanner sc = new Scanner(System.in); // while (true) { // System.out.println("请您输入要修改数量的商品名称:"); // String name = sc.next(); // com.itheima.demo.Article a = getArticleByName(name , shopCar ); // 返回根据商品名称找到的商品对象,也可能返回null // if(a != null){ // 找到了商品对象 // System.out.println("请您输入修改后购买的数量:"); // int buyNumber = sc.nextInt(); // a.buyNumber = buyNumber; // 更新修改数量 // System.out.println("该商品的购买数量修改了!"); // break; // 商品修改完成break // }else { // 没有找到商品对象,继续输入,找到为止 // System.out.println("购物车中没有该商品信息"); // } // } // } // // public static com.itheima.demo.Article getArticleByName(String name , com.itheima.demo.Article[] shopCar){ // // 查根据名字返回商品对象:Article // for (int i = 0; i < shopCar.length; i++) { // com.itheima.demo.Article a = shopCar[i]; // 商品不为null // if(a != null && a.name.equals(name) ){ // return a; // a.name.equals(name) 判断 a这个商品的name字段等于我们预期传递来的参数name,是不是我们要找的 // } // } // return null; // 循环了 100 个了,还没有找到,就返回 null // } // // public static void queryArticle(com.itheima.demo.Article[] shopCar) { // System.out.println("============查询购物车信息=========================="); // System.out.println("商品名称\t商品价格\t商品的购买数量"); // // 展示购物车的商品信息 // for (int i = 0; i < shopCar.length; i++) { // com.itheima.demo.Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址 // if(a != null){ // 不为null 说明有数据可以展示商品对象 // System.out.println(a.name +"\t" + a.price + "\t" + a.buyNumber); // }else { // 为null说明循环遍历结束了 // return; // break; 也可以 // } // } // } // // public static void addArticle(com.itheima.demo.Article[] shopCar) { // 参数接受一个商品数组购物车 // Scanner sc = new Scanner(System.in); // 1:录入用户输入的商品信息 // System.out.println("请您输入商品的名称:"); // String name = sc.next(); // System.out.println("请您输入商品的价格:"); // double price = sc.nextDouble(); // System.out.println("请您输入购买商品的数量:"); // int buyNumber = sc.nextInt(); // // // 2:创建一个商品对象,封装这些商品信息 // Article a = new Article(); // a.setName(name); // a.setPrice(price); // a.setBuyNumber(buyNumber); // // // 3:添加商品:遍历这个购物车数组对象,看哪个位置是null,如果是null ,把商品对象添加进去 // for (int i = 0; i < shopCar.length; i++) { // if(shopCar[i] == null){ // == null 说明 这个位置没有元素,就把商品对象添加到购物车里这个位置,存储的商品对象的地址 // shopCar[i] = a; // 把商品对象添加到这个位置了,商品对象添加到购物车数组中去 // break; // } // } // System.out.println("添加成功!"); // } //}
12:成员变量和局部变量的区别
13:面向对象综合案例
14:面向对象之综合案例——购物车
package com.itheima.demo; public class Article { // 商品对象 int id; // 商品编号 String name; // 名称 double price; // 价格 int buyNumber; // 购买数量 }
package com.itheima.demo; import java.util.Scanner; /** 需求:模拟购物车的功能。 1、定义一个商品类:Article(属性:名称、价格) 2、定义一个数组容器存储商品对象的,代表购物车对象。数组对象,容器,存储商品 3:界面架构,用户选择操作功能 */ public class Test { public static void main(String[] args) { Article[] shopCar = new Article[10]; // a、定义一个数组存储商品对象的,代表购物车对象。 // Article:引用类型,商品类型的数组,里面存储商品对象。长度10,这里存储的还是商品的地址,默认值为null // b、让用户选择功能 while (true) { Scanner sc = new Scanner(System.in); System.out.println("添加商品:add"); System.out.println("查看商品:query"); System.out.println("修改数量:update"); System.out.println("结算价格:pay"); System.out.println("请您选择要操作的功能:"); String command = sc.next(); switch (command) { case "add": addArticle(shopCar); // 把商品加入到购物车中去,参数是 shopCar 购物车去添加商品 alt + 回车 :快捷生成方法 break; case "query": queryArticle(shopCar); // 查看购物车中的商品信息 break; case "update": updateArticle(shopCar); // 修改商品的购买数量 break; case "pay": calcPayMoney(shopCar); // 查结算金额 break; case "Q": break; default: // 输入命令有问题走这个 System.out.println("当前命令输入有误!"); } break; } } private static void calcPayMoney(Article[] shopCar) { queryArticle(shopCar); double money = 0; // 准备一个double类型的变量统计总金额 for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; if(a != null){ money += (a.price * a.buyNumber); }else { break; } } System.out.println("本次商品购买的总价为:" + money); } public static void updateArticle(Article[] shopCar) { Scanner sc = new Scanner(System.in); while (true) { System.out.println("请您输入要修改数量的商品名称:"); String name = sc.next(); Article a = getArticleByName(name , shopCar ); // 返回根据商品名称找到的商品对象,也可能返回null if(a != null){ // 找到了商品对象 System.out.println("请您输入修改后购买的数量:"); int buyNumber = sc.nextInt(); a.buyNumber = buyNumber; // 更新修改数量 System.out.println("该商品的购买数量修改了!"); break; // 商品修改完成break }else { // 没有找到商品对象,继续输入,找到为止 System.out.println("购物车中没有该商品信息"); } } } public static Article getArticleByName(String name , Article[] shopCar){ // 查根据名字返回商品对象:Article for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; // 商品不为null if(a != null && a.name.equals(name) ){ return a; // a.name.equals(name) 判断 a这个商品的name字段等于我们预期传递来的参数name,是不是我们要找的 } } return null; // 循环了 100 个了,还没有找到,就返回 null } public static void queryArticle(Article[] shopCar) { System.out.println("============查询购物车信息=========================="); System.out.println("商品名称\t商品价格\t商品的购买数量"); // 展示购物车的商品信息 for (int i = 0; i < shopCar.length; i++) { Article a = shopCar[i]; // 接受商品变量,a指向商品变量的地址 if(a != null){ // 不为null 说明有数据可以展示商品对象 System.out.println(a.name +"\t" + a.price + "\t" + a.buyNumber); }else { // 为null说明循环遍历结束了 return; // break; 也可以 } } } public static void addArticle(Article[] shopCar) { // 参数接受一个商品数组购物车 Scanner sc = new Scanner(System.in); // 1:录入用户输入的商品信息 System.out.println("请您输入商品的名称:"); String name = sc.next(); System.out.println("请您输入商品的价格:"); double price = sc.nextDouble(); System.out.println("请您输入购买商品的数量:"); int buyNumber = sc.nextInt(); // 2:创建一个商品对象,封装这些商品信息 Article a = new Article(); a.name = name; // 对象里面的成员变量赋值 a.price = price; a.buyNumber = buyNumber; // 3:添加商品:遍历这个购物车数组对象,看哪个位置是null,如果是null ,把商品对象添加进去 for (int i = 0; i < shopCar.length; i++) { if(shopCar[i] == null){ // == null 说明 这个位置没有元素,就把商品对象添加到购物车里这个位置,存储的商品对象的地址 shopCar[i] = a; // 把商品对象添加到这个位置了,商品对象添加到购物车数组中去 break; } } System.out.println("添加成功!"); } }
15:String类概述
16:String对象的内存概述——之 字符串常量池
String是不可变字符串的原因?
String变量每次的修改其实都是产生并指向了新的字符串对象。
原来的字符串对象都是没有改变的,所以称不可变字符串
17:String字符串——之内容比较 equals 和 equalsIgnoreCase
String引用数据类型字符串的内容比较不适合用“==”比较
基本数据类型比较时使用 == 比较
package com.itheima.string; import java.util.Scanner; /** == 判断的还是 值相等,基本数据类型变量存储的就是本身的值,可以使用 == 来进行比较 引用数据类型【string 这些类】,存储的放的是地址,可能内容一样,地址不一样,不适合使用 == 来进行比较,使用String提供的equals方法 */ public class StringAPIEqualsDemo4 { public static void main(String[] args) { // 1、正确登录名和密码 String okName = "itheima"; String okPassword = "123456"; // 2、请您输入登录名称和密码 Scanner sc = new Scanner(System.in); System.out.println("登录名称:"); String name = sc.next(); System.out.println("登录密码:"); String password = sc.next(); if(name == okName && okPassword==password){ // 使用 == 判断是否相等 System.out.println("==判断 name和 okName是相等的"); } // 当前无法使用 == 判断,因为 == 在这里比较的是地址 okName指向的地址是常量池 name接受用户输入信息创建的,放在堆内存里的 指向的地址不一致 else { System.out.println("==判断 name和 okName是不相等的"); } // 3、判断用户输入的登录名称和密码与正确的内容是否相等。 if(okName.equals(name ) && okPassword.equals(password)){ System.out.println("登录成功!"); }else { System.out.println("用户名或者密码错误了!"); } // 4、忽略大小写比较内容的Api: 一般用于比较验证码这样的业务逻辑 String sysCode = "23AdFh"; String code1 = "23aDfH"; System.out.println(sysCode.equals(code1)); // false System.out.println(sysCode.equalsIgnoreCase(code1)); // true equalsIgnoreCase忽略大小写比较内容 } }
18:String字符串——之 遍历,替换,截取,分割操作
package com.itheima.string; /** 目标:了解String类的特点:String类不可变的原理 java.lang.String 类代表字符串,String类定义的变量可以用于指向字符串对象,然后操作该字符串 Java 程序中的所有字符串文字(例如“abc”)都为此类的对象
双引号标起来的都可以说是字符串对象 String类的特点详解 String其实常被称为不可变字符串类型,它的对象在创建后不能被更改 以“”方式给出的字符串对象,在字符串常量池中存储【堆内存】 "传智"字符串存储在堆内存字符串常量池,name这个变量指向字符串地址空间 name存储的是地址:那么System.out.println(name);为什么打印的是字符串内容 这个 String 类的特殊改发,通过地址把内容输出了【继承里体现】存储的本质还是地址 字符串常量池中存储: "传智" "教育" "中心" name一开始指向 "传智" 然后 "传智" + "教育" 连接成一个新的字符串对象 运算出来的对象存储在 堆内存中 然后name指向最新的 "传智" + "教育" 本质上创建的字符串对象 "传智" "教育" "中心" 没有改变,一直存储在 字符串常量池中 string类型变量name从 指向 "传智" 变成了指向 "传智教育" ,【原来的对象 "传智" 没有改变】 【所以 string 对象是不可变的对象】【下面的中心运算和上面的类似】 */ public class StringDemo1 { public static void main(String[] args) { String name = "传智"; name += "教育"; // name = name + "教育" name这个对象被覆盖重写指向一个新的 String了,name指向的变量变化了 name += "中心"; System.out.println(name); } }
package com.itheima.string; /** 目标:掌握String常用的其他API。 */ public class StringAPIOtherDemo5 { public static void main(String[] args) { // 1、public int length(): 获取字符串的长度 String name = "我爱你中国love"; System.out.println(name.length()); // 2、public char charAt(int index): 获取某个索引位置处的字符 char c = name.charAt(1); // 返回一个字符 System.out.println(c); System.out.println("------------遍历字符串中的每个字符--------------"); for (int i = 0; i < name.length(); i++) { char ch = name.charAt(i); // ctrl + alt+ v System.out.println(ch); } // 3、public char[] toCharArray():: 把字符串转换成字符数组 char[] chars = name.toCharArray(); // 字符串转化成一个字符数组 for (int i = 0; i < chars.length; i++) { char ch = chars[i]; System.out.println(ch); } // 4、public String substring(int beginIndex, int endIndex) :截取内容,(包前不包后的) String name2 = "Java是最厉害的编程语言!"; // 01234567 89 String rs = name2.substring(0, 9); // 包前不包后 System.out.println(rs); String rs1 = name2.substring(4, 9); System.out.println(rs1); // 5、public String substring(int beginIndex):从当前索引一直截取到末尾 String rs2 = name2.substring(4); // 从4位置截取到尾 System.out.println(rs2); // 6、public String replace(CharSequence target, CharSequence replacement) 敏感词替换:replace String name3 = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖"; String rs3 = name3.replace("金三胖", "***"); // 返回的是一个新的内容,原来的name3内容不替换的 System.out.println(rs3); // 7、public boolean contains(CharSequence s) 包含 System.out.println(name3.contains("金三胖")); // true System.out.println(name3.contains("金二胖")); // false // 8、public boolean startsWith(String prefix) 以什么开始 System.out.println(name3.startsWith("金三胖")); System.out.println(name3.startsWith("金三胖是最厉害的")); System.out.println(name3.startsWith("金三胖是最厉害的2")); // 9、public String[] split(String s): 按照某个内容把字符串分割成字符串数组返回。 String name4 = "王宝强,贾乃亮,陈羽凡"; String[] names = name4.split(","); for (int i = 0; i < names.length; i++) { System.out.println("选择了:" + names[i]); } } }
18:String简单案例
package com.itheima.string; import java.util.Random; /** 练习题:使用String完成随机生成5位的验证码。 */ public class StringExec6 { public static void main(String[] args) { // 1、定义可能出现的字符信息 String datas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // 2、循环5次,每次生成一个随机的索引,提取对应的字符连接起来即可 String code = ""; Random r = new Random(); // 随机数对象 for (int i = 0; i < 5; i++) { // 随机一个索引 int index = r.nextInt(datas.length()); char c = datas.charAt(index); code += c; } // 3、输出字符串变量即可 System.out.println(code); } }
package com.itheima.string; import java.util.Random; import java.util.Scanner; /** 练习题:模拟用户登录,3次登录机会、 */ public class StringExec7 { public static void main(String[] args) { // 1、定义正确的登录名称和密码 String okLoginName = "admin"; String okPassword = "itheima"; // 2、定义一个循环,循环3次,让用户登录 Scanner sc = new Scanner(System.in); for (int i = 1; i <= 3; i++) { System.out.println("请您输入登录名称:"); String loginName = sc.next(); System.out.println("请您输入登录密码:"); String password = sc.next(); if(okLoginName.equals(loginName)){ // 3、先判断登录是否成功! if(okPassword.equals(password)){ // 4、再判断密码是否正确 System.out.println("登录成功!欢迎进入系统随意浏览~~~~"); break; }else { // 密码错误了 System.out.println("您的密码不正确!您还剩余" + (3 - i) +"次机会登录!"); } }else { System.out.println("您的登录名称不正确!您还剩余" + (3 - i) +"次机会登录!"); } } } }
package com.itheima.string; import java.util.Scanner; /** 练习题:手机号码屏蔽 键盘录入一个手机号,将中间四位号码屏蔽,最终效果为: 分析 键盘录入一个字符串。 调用字符串对象的截取API,截取字符串前三位、后四位。 将前三位 连接“****”然后继续连接后四位,输出最终结果即可 */ public class StringExec8 { public static void main(String[] args) { // 1、键盘录入一个手机号码 Scanner sc = new Scanner(System.in); System.out.println("请您输入您的手机号码:"); String tel = sc.next(); // 2、截取号码的前三位,后四位 18665666520 String before = tel.substring(0, 3); // 0 1 2 String after = tel.substring(7); // 从索引7开始截取到手机号码的末尾 String s = before + "****" + after; System.out.println(s); } }
19:String创建字符串对象的 2 种方式
package com.itheima.string; /** 目标:String类创建字符串对象的2种方式 方式一:直接使用“”定义。(推荐方式) 方式二:通过String类的构造器创建对象 以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。【节省内存资源】 比如 a = "中国" 在一个项目中可能出现几百上千次,"中国"这个对象内容一致不可变,所以 出现几千次存储一份就行了 通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中 */ public class StringDemo2 { public static void main(String[] args) { // 方式一:直接使用双引号得到字符串对象 String name = "我爱你中国"; System.out.println(name); // 特殊优化,本身 name存储的是地址,但是这里打印还是根据地址打印了地址存储的内容 // 方式二: // 1、public String(): 创建一个空白字符串对象,不含有任何内容 (几乎不用) String s1 = new String(); // s1 = "" System.out.println(s1); // 2、public String(String): 根据传入的字符串内容,来创建字符串对象(几乎不用) String s2 = new String("我是中国人"); System.out.println(s2); // 3、public String(char[] c): 根据字符数组的内容,来创建字符串对象 char[] chars = {'a' , 'b' , '中', '国'}; // 【字符数组】 String s3 = new String(chars); // 把字符数组里的内容拼接起来 System.out.println(s3); // 4、public String(byte[] b): 根据字节数组的内容,来创建字符串对象 -128-127【字节数组】 byte[] bytes = {97, 98, 99, 65, 66, 67}; String s4 = new String(bytes); // 把字节数组里的整数全部转化成字符 内容再拼接成一个字符串 System.out.println(s4); System.out.println("---------------------------------------"); String ss1 = "abc"; String ss2 = "abc"; System.out.println(ss1 == ss2); // == 比较两个字符串变量存储的地址 // == 比较的是ss1的值和ss2的值,也就是两个变量指向的字符串的内容地址 // 【因为以“”方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份】 所以这里返回 true char[] chars1 = {'a' , 'b' , 'c'}; String ss3 = new String(chars1); String ss4 = new String(chars1); System.out.println(ss3 == ss4); // 通过构造器new对象,每new一次都会产生一个新对象,放在堆内存中 // 每次 new一下在堆内存中产生不同的对象,所以这里返回 false } }
20:Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 "abc"
package com.itheima.string; public class StringDemo3 { public static void main(String[] args) { String s1 = "abc"; String s2 = "a" + "b" + "c"; System.out.println(s1 == s2); System.out.println("----------------------"); ms1(); System.out.println("----------------------"); ms2(); System.out.println("----------------------"); ms3(); } public static void ms1() { String s2 = new String("abc"); // 字符串常量池 存储 "abc" + 堆内存中new 存储一个 "abc",s2指向堆内存的 "abc" String s1 = "abc"; // 发生 字符串常量池中有 "abc" 那么 这里s1直接指向常量池中的 "abc",不创建了 System.out.println(s1 == s2); // s1 和s2 指向不同 // } public static void ms2() { String s1 = "abc"; // 字符串常量池 存储 "abc",s1指向常量池的 "abc" String s2 = "ab"; // 字符串常量池 存储 "ab" String s3 = s2 + "c"; // 计算出来的等同 new创建,堆内存中再存储一个 "abc",s3是运算出来的,s3指向堆内存中的 "abc" System.out.println(s1 == s3); // false // 这里没有 编译优化机制,因为需要代码跑起来才知道 s2等于啥,跑起来才知道 s2指向"ab"的 // 变量和字面量的区别 } public static void ms3() { String s1 = "abc"; String s2 = "a" + "b" + "c"; System.out.println(s1 == s2); // true // Java存在编译优化机制,程序在编译时: “a” + “b” + “c” 会直接转成 "abc" // 编译把代码先 翻译成 class文件,翻译成class文件的时候 s2已经等于 "abc" 了 // java代码运行的时候 s1 和s2 都指向 常量池的 "abc",返回 true // 假设不这样优化,需要常量池产生 3个对象 "a" "b" "c",然后new运算在堆内存中再生成一个 "abc" ——>浪费性能和内存【不存储那么多数据,少+ 和new两步运算】 } }
21:集合的概念 ArryList
package com.itheima.arraylist; import java.util.ArrayList; /** 目标: 创建ArrayList对象,代表集合容器,往里面添加元素。 引用类型变量 list 存储的是集合对象的地址 打印的时候会去获取 集合地址里存储的内容【改进】 add 方法 会有一个布尔类型的返回值,添加成功返回真,添加失败返回假,ArrayList集合一般不会添加元素失败 */ public class ArrayListDemo1 { public static void main(String[] args) { ArrayList list = new ArrayList(); // 1、创建ArrayList集合的对象【调用 ArrayList 的无参构造器】 // 2、添加数据 list.add("Java"); list.add("Java"); list.add("MySQL"); list.add("黑马"); list.add(23); list.add(23.5); list.add(false); System.out.println(list.add('中')); System.out.println(list); // 3、给指定索引位置插入元素,插入后 后面的元素自动往后移动一位 list.add(1, "赵敏"); System.out.println(list); } }
22:ArryList集合——泛型概念【ArryList<E>】
package com.itheima.arraylist; import java.util.ArrayList; /** 目标: 能够使用泛型约束ArrayList集合操作的数据类型 ArrayList 容器默认能够存储任意类型的元素,实际开发不建议这样做,因为java是强类型的语言 最好需要能够确定数据的类型,比如存分数 泛型概述 ArrayList<E>:其实就是一个泛型类,可以在编译阶段约束集合对象只能操作某种数据类型 ArrayList<String> :此集合只能操作字符串类型的元素。 ArrayList<Integer>:此集合只能操作整数类型的元素。 泛型只能支持引用数据类型,不支持基本数据类型,里面存储的都是一个对象,整数的引用类型 Integer 泛型定义集合就是一直规范和标准 ArrayList list = new ArrayList(); 默认是就可以存储任意类型的集合 但是一般不这样写 ArrayList<object> list = new ArrayList<object>(); 这样使用Object泛型来定义,标准化,这样也可以存储任意数据类型--标准 定义集合都要采用泛型 */ public class ArrayListDemo2 { public static void main(String[] args) { // ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<>(); // JDK 1.7开始,泛型后面的类型申明可以不写 list.add("Java"); list.add("MySQL"); // list.add(23); // list.add(23.5); ArrayList<Integer> list2 = new ArrayList<>(); list2.add(23); list2.add(100); // list2.add("Java"); } }
23:ArryList集合——>之遍历,遍历并删除元素,存储自定义类型,元素搜索
package com.itheima.arraylist; import java.util.ArrayList; /** 目标:掌握ArrayList集合的常用API */ public class ArrayListDemo3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("Java"); list.add("Java"); list.add("MySQL"); list.add("MyBatis"); list.add("HTML"); // 1、public E get(int index):获取某个索引位置处的元素值 String e = list.get(3); System.out.println(e); // 2、public int size():获取集合的大小(元素个数) System.out.println(list.size()); // 3、完成集合的遍历 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } // 4、public E remove(int index):删除某个索引位置处的元素值,并返回被删除的元素值 System.out.println(list); // [Java, Java, MySQL, MyBatis, HTML] String e2 = list.remove(2); // 删除某个索引位置处的元素值,并返回被删除的元素值 System.out.println(e2); System.out.println(list); // 5、public boolean remove(Object o):直接删除元素值,删除成功返回true,删除失败返回false System.out.println(list.remove("MyBatis")); // 删除的值 集合里有多个,只会默认删除前面的 第一个数据 System.out.println(list); ArrayList<String> list1 = new ArrayList<>(); list1.add("Java"); list1.add("王宝强"); list1.add("Java"); list1.add("MySQL"); System.out.println(list1); // 只会删除第一次出现的这个元素值,后面的不删除 System.out.println(list1.remove("Java")); System.out.println(list1); // 6、public E set(int index,E element):修改某个索引位置处的元素值。 String e3 = list1.set(0 , "贾乃亮"); // 返回修改前的值 System.out.println(e3); System.out.println(list1); } }
24:ArryList集合里存储的数据内存分析
25:ArryList集合简单案例
package com.itheima.arraylist; import java.util.ArrayList; /** 案例:从集合中遍历元素且删除。 ArrayList<Integer> scores = new ArrayList<>(); 存储整数引用类型 ArrayList<Double> scores = new ArrayList<>(); 存储 小数引用类型 边遍历 边删除 操作需要各位注意 */ public class ArrayListTest4 { public static void main(String[] args) { // 1、创建集合对象:存入学生成绩(98,77,66,89,79,50,100) ArrayList<Integer> scores = new ArrayList<>(); scores.add(98); scores.add(77); scores.add(66); scores.add(89); scores.add(79); scores.add(50); scores.add(100); System.out.println(scores); // [98, 77, 66, 89, 79, 50, 100] // [98, 66, 89, 50, 100] // i // 1、遍历集合中的每个元素 // for (int i = 0; i < scores.size(); i++) { // int score = scores.get(i); // // 2、判断这个分数是否低于80分,如果低于则从集合中删除它 // if(score < 80){ // scores.remove(i); // } // } // System.out.println(scores); // 这样写 有 bug,无法删除 80分的数据 // i=0 一开始在98 的位置 不低于80,不删除 // i=1 在77的位置,77小于80把77删除,77删除了66往前移动了到 i=1的位置了 // i=2 到了89的位置了,不删除 // for循环执行的时候会一直调用()里的代码,scores.size()一直获取 scores的长度,因为要一直判断条件是否还满足 // 删除元素之后后面的元素往前移动导致跳位了 // [98, 77, 66, 89, 79, 50, 100] // [98, 89, 100] // i // 解决方案一:每删除成功一个数据,i往后退一步,保证下次回到位置,这样不会跳过数据 // 解决方案二:从后面倒着遍历删除就可以 i在100最后面的位置,起始索引集合大小-1,i往前走最终走到0这个位置所以 i >= 0 ,小于0就走完了 // 从后往前走需要 i-- // 倒着删除,删除一个数据后经过扫描的数据往前提,所有的前面的数据都能扫描到,不会跳数据 for (int i = scores.size() - 1; i >= 0 ; i--) { int score = scores.get(i); // 提取数据 // 2、判断这个分数是否低于80分,如果低于则从集合中删除它 if(score < 80){ scores.remove(i); } } System.out.println(scores); } }
package com.itheima.arraylist; import java.util.ArrayList; /** 案例:集合存储自定义元素并遍历。 需求:定义电影类(名称,分值,演员),创建3个电影对象,代表三部影片,存入集合中并遍历。 《肖生克的救赎》, 9.7 , 罗宾斯 《霸王别姬》, 9.6 , 张国荣、张丰毅 《阿甘正传》, 9.5 , 汤姆.汉克斯 */ public class ArrayListTest5{ public static void main(String[] args) { // 1、定义一个电影类:Movie ArrayList<Movie> movies = new ArrayList<>(); // 2、定义一个ArrayList集合存储这些影片对象。 // 3、创建影片对象封装电影数据,把对象加入到集合中去。 // Movie m1 = new Movie("《肖生克的救赎》", 9.7 , "罗宾斯"); // movies.add(m1); movies.add(new Movie("《肖生克的救赎》", 9.7 , "罗宾斯")); movies.add(new Movie("《霸王别姬》", 9.6 , "张国荣、张丰毅")); movies.add(new Movie("《阿甘正传》", 9.5 , "汤姆.汉克斯")); System.out.println(movies); // 打印:[com.itheima.arraylist.Movie@776ec8df, com.itheima.arraylist.Movie@4eec7777, com.itheima.arraylist.Movie@3b07d329] // 打印集合里的内容,因为这里的Movie类没特殊处理,打印的还是集合里存储的对象的地址,Movie不像String做了特殊处理,集合里存储的就是对象的地址 // 4、遍历集合中的影片对象并展示出来 for (int i = 0; i < movies.size(); i++) { Movie movie = movies.get(i); // movies.get(i)取值的是 影片对象的地址 System.out.println("片名:" + movie.getName()); System.out.println("评分:" + movie.getScore()); System.out.println("主演:" + movie.getActor()); } } }
package com.itheima.arraylist; import java.util.ArrayList; import java.util.Scanner; /** 案例:学生信息系统:展示数据,并按照学号完成搜索 学生类信息(学号,姓名,性别,班级) 测试数据: "20180302","叶孤城",23,"护理一班" "20180303","东方不败",23,"推拿二班" "20180304","西门吹雪",26,"中药学四班" "20180305","梅超风",26,"神经科2班" */ public class ArrayListTest6 { public static void main(String[] args) { // 1、定义一个学生类,后期用于创建对象封装学生数据 // 2、定义一个集合对象用于装学生对象 ArrayList<Student> students = new ArrayList<>(); students.add(new Student("20180302","叶孤城",23,"护理一班")); students.add(new Student("20180303","东方不败",23,"推拿二班")); students.add(new Student( "20180304","西门吹雪",26,"中药学四班")); students.add(new Student( "20180305","梅超风",26,"神经科2班")); System.out.println("学号\t\t名称\t\t年龄\t\t班级"); // 3、遍历集合中的每个学生对象并展示其数据 for (int i = 0; i < students.size(); i++) { Student s = students.get(i); System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t" + s.getAge() +"\t\t" + s.getClassName()); } // 4、让用户不断的输入学号,可以搜索出该学生对象信息并展示出来(独立成方法) Scanner sc = new Scanner(System.in); while (true) { System.out.println("请您输入要查询的学生的学号:"); String id = sc.next(); Student s = getStudentByStudyId(students, id); // 判断学号是否存在 if(s == null){ System.out.println("查无此人!"); }else { // 找到了该学生对象了,信息如下 System.out.println(s.getStudyId() +"\t\t" + s.getName()+"\t\t" + s.getAge() +"\t\t" + s.getClassName()); } } } /** 根据学号,去集合中找出学生对象并返回。 * @param students * @param studyId * @return */ public static Student getStudentByStudyId(ArrayList<Student> students, String studyId){ // 返回学生对象 for (int i = 0; i < students.size(); i++) { // 遍历集合中的学生对象 Student s = students.get(i); if(s.getStudyId().equals(studyId)){ // 判断学生id是不是等于传入的id,找到了返回s学生对象 return s; } } return null; // 查无此学号!可能循环找完了都没有匹配到学生对象,返回null } }
package com.itheima.arraylist; public class Movie { private String name; // 电影名字 private double score; // 电影评分 private String actor; // 电影主演 public Movie() { // 无参构造器 } public Movie(String name, double score, String actor) { // 有参构造器 this.name = name; this.score = score; this.actor = actor; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } public String getActor() { return actor; } public void setActor(String actor) { this.actor = actor; } }
package com.itheima.arraylist; public class Student { private String studyId; private String name; private int age; private String className; public Student() { } public Student(String studyId, String name, int age, String className) { this.studyId = studyId; this.name = name; this.age = age; this.className = className; } public String getStudyId() { return studyId; } public void setStudyId(String studyId) { this.studyId = studyId; } 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 getClassName() { return className; } public void setClassName(String className) { this.className = className; } }
26:第一阶段综合案例 ——>ATM取款系统
package com.itheima; /** 账户类:创建账户信息 */ public class Account { /** 成员变量,私有 */ private String cardId; // 卡号 private String userName; // 用户名 private String passWord; // 密码 private double money; // 账户余额 private double quotaMoney; // 每次取现额度 // 默认有无参构造器,这里不写了 public String getCardId() { return cardId; } public void setCardId(String cardId) { this.cardId = cardId; } 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; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public double getQuotaMoney() { return quotaMoney; } public void setQuotaMoney(double quotaMoney) { this.quotaMoney = quotaMoney; } }
package com.itheima; import java.util.ArrayList; import java.util.Random; import java.util.Scanner; /** ATM系统的入口类 private static void login:private修饰的方法表示只能本地访问 */ public class ATMSystem { public static void main(String[] args) { // 1、定义账户类 Account // 2、定义一个集合容器,负责以后存储全部的账户对象,进行相关的业务操作。 ArrayList<Account> accounts = new ArrayList<>(); // 3、展示系统的首页 Scanner sc = new Scanner(System.in); while (true) { System.out.println("===============ATM系统================="); System.out.println("1、账户登录"); System.out.println("2、账户开户"); System.out.println("请您选择操作:"); int command = sc.nextInt(); // 接受整型,switch分支 switch (command){ case 1: login(accounts, sc); // 用户登录操作 break; case 2: register(accounts,sc); // 用户账户开户(ALT + ENTER快捷生成方法) break; default: System.out.println("您输入的操作命令不存在~~"); } } } /** * 登录功能 * @param accounts 全部账户对象的集合 * @param sc 扫描器 */ private static void login(ArrayList<Account> accounts, Scanner sc) { System.out.println("===================系统登录操作========================"); // 1、判断账户集合中是否存在账户,如果不存在账户,登录功能不能进行。 if(accounts.size() == 0) { System.out.println("对不起,当前系统中,无任何账户,请先开户,再来登录~~"); return; // 卫语言风格,结束方法的执行。 } // 2、正式进入登录操作 while (true) { System.out.println("请您输入登录卡号:"); String cardId = sc.next(); Account acc = getAccountByCardId(cardId, accounts); // 3、判断卡号是否存在:根据卡号去账户集合中查询账户对象 if(acc != null){ // 卡号存在的 while (true) { System.out.println("请您输入登录密码:"); String passWord = sc.next(); // 4、让用户输入密码,认证密码 if(acc.getPassWord().equals(passWord)) { // 判断当前账户对象的密码是否与用户输入的密码一致 // 登录成功了 System.out.println("恭喜您," + acc.getUserName() +"先生/女生进入系统,您的卡号是:" + acc.getCardId()); // .... 查询 转账 取款 .... showUserCommand(sc, acc, accounts); // 展示登录后的操作页。 return; // 干掉登录方法 }else { // 密码有问题,再次输入继续认证 System.out.println("对不起,您输入的密码有误~~"); } } }else { // 卡号不存在 System.out.println("对不起,系统中不存在该账户卡号~~"); } } } /** 展示登录后的操作页 */ private static void showUserCommand(Scanner sc, Account acc, ArrayList<Account> accounts) { while (true) { 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("6、退出"); System.out.println("7、注销账户"); System.out.println("请选择:"); int command = sc.nextInt(); switch (command) { case 1: showAccount(acc); // 查询账户(展示当前登录的账户信息) break; case 2: depositMoney(acc, sc); // 存款 break; case 3: drawMoney(acc, sc); // 取款 break; case 4: transferMoney(sc, acc, accounts); // 转账 break; case 5: updatePassWord(sc, acc); // 修改密码 return; // 让当前方法停止执行,跳出去 case 6: System.out.println("退出成功,欢迎下次光临"); // 退出 return; // 让当前方法停止执行,跳出去 干掉当前方法的执行, case 7: if(deleteAccount(acc,sc,accounts)){ // 注销账户 // 销户成功了,回到首页 return; // 让当前方法停止执行,跳出去 }else { // 没有销户成功, 还是在操作页玩 break; } default: System.out.println("您输入的操作命令不正确~~"); } } } /** * 销户功能 * @param acc * @param sc * @param accounts */ private static boolean deleteAccount(Account acc, Scanner sc, ArrayList<Account> accounts) { System.out.println("===================用户销户========================"); System.out.println("您真的要销户?y/n"); String rs = sc.next(); switch (rs) { case "y": // 真正的销户 // 从当前账户集合中,删除当前账户对象,销毁就完成了。 if(acc.getMoney() > 0){ System.out.println("您账户中还有钱没有取完,不允许销户~"); }else { accounts.remove(acc); System.out.println("您的账户销户完成~~"); return true; // 销户成功 } break; default: System.out.println("好的,当前账户继续保留~"); } return false; } /** * 修改密码 * @param sc 扫描器 * @param acc 当前登录成功的账户对象。 */ private static void updatePassWord(Scanner sc, Account acc) { System.out.println("===================用户密码修改========================"); while (true) { System.out.println("请您输入当前密码:"); String passWord = sc.next(); if(acc.getPassWord().equals(passWord)){ // 1、判断这个密码是否正确 while (true) { // 密码正确 // 2、输入新密码。 System.out.println("请您输入新密码:"); String newPassWord = sc.next(); System.out.println("请您确认新密码:"); String okPassWord = sc.next(); if(newPassWord.equals(okPassWord)) { // 2次密码一致,可以修改了 acc.setPassWord(newPassWord); System.out.println("恭喜您,您密码修改成功了~~"); return; }else { System.out.println("您输入的2次密码不一致~~"); } } }else { System.out.println("您输入的密码不正确~"); } } } /** * 转账功能 * @param sc 扫描器 * @param acc 自己的账户对象 * @param accounts 全部账户的集合。 */ private static void transferMoney(Scanner sc, Account acc, ArrayList<Account> accounts) { System.out.println("===================用户转账操作========================"); if(accounts.size() < 2){ // 1、判断是否足够2个账户 System.out.println("当前系统中,不足2个账户,不能进行转账,请去开户吧~~"); return; // 不能转账那么 return 结束当前方法 } if(acc.getMoney() == 0) { // 2、判断自己的账户是否有钱 System.out.println("对不起,您自己都都没钱,就别转了吧~~"); return; // 没有前那么 结束当前转账方法 } while (true) { // 有两个账户并且 账号有钱,真正转账逻辑 // 3、真正开始转账 System.out.println("请您输入对方账户的卡号:"); String cardId = sc.next(); if(cardId.equals(acc.getCardId())){ // 这个卡号不能是自己的卡号 System.out.println("对不起,您不可以给自己进行转账~~"); continue; // 结束当次执行,死循环进入下一次 } Account account = getAccountByCardId(cardId, accounts); // 判断这个卡号是存在的:根据这个卡号去查询对方账户对象。 if(account == null){ // 卡号不存在 System.out.println("对不起,您输入对方的这个账号不存在~~"); }else { // 这个账户对象存在了:继续认证他的姓氏 String userName = account.getUserName(); // 黑马周芷若 获取的全名 String tip = "*" + userName.substring(1); // userName.substring(1); 从 第1 个位置开始截 System.out.println("请您输入["+ tip +"]的姓氏"); String preName = sc.next(); // 接受姓氏 if(userName.startsWith(preName)) { // 认证姓氏是否输入正确。 while (true) { // 认证通过,真正开始转账了 System.out.println("请您输入转账金额:"); double money = sc.nextDouble(); if(money > acc.getMoney()) { // 判断余额是否足够 System.out.println("对不起,您余额不足,您最多可以转账:" + acc.getMoney()); }else { // 余额足够,可以转了 acc.setMoney(acc.getMoney() - money); account.setMoney(account.getMoney() + money); System.out.println("转账成功!您的账户还剩余:" + acc.getMoney()); return; // 直接干掉转账方法 } } }else { // 认证姓氏 错误 System.out.println("对不起,您输入的信息有误~~"); } } } } /** * 取钱功能 * @param acc 当前账户对象 * @param sc 扫描器 */ private static void drawMoney(Account acc, Scanner sc) { System.out.println("===================用户取钱操作========================"); if(acc.getMoney() < 100) { // 1、判断是否足够100元 System.out.println("对不起,当前账户中不够100元,不能取钱~"); return; } while (true) { System.out.println("请您输入取款金额:"); // 2、提示用户输入取钱金额 double money = sc.nextDouble(); if(money > acc.getQuotaMoney()) { // 3、判断这个金额是否满足要求。 System.out.println("对不起,您当前取款金额超过每次限额,每次最多可取:" + acc.getQuotaMoney()); }else { // 没有超过当次限额。 if(money > acc.getMoney()){ // 4、判断是否超过了账户的总余额。 System.out.println("余额不足,您账户目前总余额是:" + acc.getMoney()); }else { // 可以取钱了。 System.out.println("恭喜您,取钱" + money +"元,成功!"); acc.setMoney(acc.getMoney() - money); // 更新余额 showAccount(acc); // 取钱结束了。 return; // 取钱取完了,那么干掉取钱方法 } } } } /** * 存钱 * @param acc 当前账户对象 * @param sc 扫描器 */ private static void depositMoney(Account acc, Scanner sc) { System.out.println("===================用户存钱操作========================"); System.out.println("请您输入存款金额:"); double money = sc.nextDouble(); // 更新账户余额:原来的钱 + 新存入的钱 acc.setMoney(acc.getMoney() + money); System.out.println("恭喜您,存钱成功,当前账户信息如下:"); showAccount(acc); } /** * 展示账户信息 * @param acc */ private static void showAccount(Account acc) { System.out.println("===================当前账户信息如下========================"); System.out.println("卡号:" + acc.getCardId()); System.out.println("户主:" + acc.getUserName()); System.out.println("余额:" + acc.getMoney()); System.out.println("限额:" + acc.getQuotaMoney()); } /** * 用户开户功能的实现 这是一个标准注释 * @param accounts 接收的账户集合。 */ private static void register(ArrayList<Account> accounts, Scanner sc) { System.out.println("===================系统开户操作========================"); Account account = new Account(); // 1、创建一个账户对象,用于后期封装账户信息 System.out.println("请您输入账户用户名:"); // 2、录入当前这个账户的信息,注入到账户对象中去 String userName = sc.next(); // 接受用户名并且属性放到类里 account.setUserName(userName); while (true) { System.out.println("请您输入账户密码:"); String passWord = sc.next(); System.out.println("请您输入确认密码:"); String okPassWord = sc.next(); if(okPassWord.equals(passWord)){ // 密码认证通过,可以注入给账户对象 account.setPassWord(okPassWord); break; // 密码已经录入成功了,死循环没有必要继续了! }else { System.out.println("对不起,您输入的2次密码不一致,请重新确认~~"); } } System.out.println("请您输入账户当次限额:"); double quotaMoney = sc.nextDouble(); // 限额 account.setQuotaMoney(quotaMoney); // 为账户随机一个8位且与其他账户的卡号不重复的号码。(独立功能,独立成方法)。 String cardId = getRandomCardId(accounts); account.setCardId(cardId); accounts.add(account); // 3、把账户对象添加到账户集合中去 System.out.println("恭喜您," + userName + "先生/女生,您开户成功,您的卡号是:" + cardId + ",请您妥善保管卡号" ); } /** * 为账户生成8位与其他账户卡号不同的号码。 * @return */ private static String getRandomCardId(ArrayList<Account> accounts) { Random r = new Random(); while (true) { // 1、先生成8位数字 String cardId = ""; // 03442522 for (int i = 0; i < 8; i++) { // 8位 cardId += r.nextInt(10); // 生成0-9的数字 } // 2、判断这个8位的卡号是否与其他账户的卡号重复了 Account acc = getAccountByCardId(cardId, accounts); // 根据这个卡号去查询账户的对象 if(acc == null){ // 说明cardId 此时没有重复,这个卡号是一个新卡号了,可以使用这个卡号作为新注册账户的卡号了 return cardId; } } } /** * 根据卡号查询出一个账户对象出来 * @param cardId 卡号 * @param accounts 全部账户的集合 * @return 账户对象 | null */ private static Account getAccountByCardId(String cardId,ArrayList<Account> accounts){ for (int i = 0; i < accounts.size(); i++) { // 遍历每个账户 Account acc = accounts.get(i); // 集合根据索引取当前对象的地址 if(acc.getCardId().equals(cardId)){ // 卡号存在,返回acc账户对象 return acc; } } return null; // 查无此账户,返回 null } }
分类:
JAVA篇
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!