基本数据类型
数据值是存储在自己的空间中。
特点:赋值给其他变量,也是赋的真实的值。
引用数据类型
数据值是存储在其他空间中,自己空间中存储的是地址值。
特点:赋值给其他变量,赋的地址值。
综合练习
使用 ctrl + alt + M 自动抽取方法
1.买飞机票
import java.util.Scanner;public class 买飞机票 {public static void main(String[] args) {// 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。// 按照如下规则计算机票价格:旺季(5-10 月)头等舱 9 折,经济舱 8.5 折,淡季(11 月到来年 4 头)头等舱 7 折,经济舱 6.5 折。 */// 分析 // 1.键盘录入机票原价、月份、头等舱或经济舱Scanner sc = new Scanner(System.in);System.out.println("请输入机票的原价");int ticket = sc.nextInt();System.out.println("请输入当前的月份");int month = sc.nextInt();System.out.println("请输入当前购买的舱位 0头等舱 1经济舱");int seat = sc.nextInt(); // 2.先判断月份是旺季还是淡季if (month >= 5 && month <= 10) { // 旺季 继续判断当前机票是经济舱还是头等舱ticket = getPrice(seat, ticket, 0.9, 0.85);} else if ((month >= 1 && month <= 4) || (month >= 11 && month <= 12)) { // 淡季ticket = getPrice(seat, ticket, 0.7, 0.65);} else { // 表示键盘录入的月份是一个非法数据System.out.println("键盘录入的月份不合法");}System.out.println(ticket);}public static int getPrice(int seat, int ticket, double v0, double v1) {if (seat == 0) { // 头等舱ticket = (int) (ticket * v0);} else if (seat == 1) { // 经济舱ticket = (int) (ticket * v1);} else {System.out.println("没有这个舱位");}return ticket;} }
2.找质数
public class 找质数 {public static void main(String[] args) { // 判断 101 ~ 200 之间有多少个素数,并输出所有素数int count = 0;for (int i = 101; i <= 200; i++) {//i 依次表示循环中的每一个数字//继续判断i是否为一个质数boolean flag = true;for (int j = 2; j < i; j++) {//j 表示2~99之间的每一个数字if (i % j == 0) {flag = false;break;}}if (flag) {System.out.println("当前数字" + i + "是质数");count++;}}System.out.println("一共有" + count + "个质数");} }
3.开发验证码
import java.util.Random;public class 开发验证码 {public static void main(String[] args) { /* 需求: 定义方法实现随机产生一个 5 位的验证码 验证码格式: 长度为 5 前四位是大写字母或者小写字母 最后一位是数字 */ // 1.大写字母和小写字母都放到数组当中char[] chs = new char[52];for (int i = 0; i < chs.length; i++) { // ASCII码表if (i <= 25) { // 添加小写字母chs[i] = (char) (97 + i);} else { // 添加大写字母chs[i] = (char) (65 + i - 26);}} // 定义一个字符串类型的变量,用来记录最终的结果String result = ""; // 2.随机抽取四次Random r = new Random();for (int i = 0; i < 4; i++) {int randomIndex = r.nextInt(chs.length); // 利用随机索引,获取对应的元素 // System.out.println(chs[randomIndex]);result += chs[randomIndex];} // System.out.println(result); // 3.随机抽取一个数字0~9result += r.nextInt(10);System.out.println(result);} }
4.数组元素的复制
public class 数组元素的复制 {public static void main(String[] args) {/* 需求: 把一个数组中的元素复制到另一个新数组中去。*/ // 分析: //1. 定义一个老数组并存储一些元素int[] arr = {1, 2, 3, 4, 5}; //2. 定义一个新数组的长度跟老数组一致int[] newArr = new int[arr.length]; //3. 遍历老数组,得到老数组中的每一个元素,依次存入到新数组当中for (int i = 0; i < arr.length; i++) {newArr[i]=arr[i];}for (int i = 0; i < newArr.length; i++) {System.out.println(newArr[i]);}} }
5.评委打分
选中一个变量 shift + F6 替换以下所有相同变量
import java.util.Scanner;public class 评委打分 {public static void main(String[] args) {// 在唱歌比赛中,有6名评委给选手打分,分数范围是[0 - 100]之间的整数。// 选手的最后得分为:去掉最高分、最低分后的4个评委的平均分,请完成上述过程并计算出选手的得分。// 分析: //1. 定义一个数组,用来存储 6 名评委的打分(0~100)int[] scoreArr = getScores();for (int i = 0; i < scoreArr.length; i++) {System.out.println(scoreArr[i]);} //2. 求出数组中的最大值int max = getMax(scoreArr); //3. 求出数组中的最小值int min = getMin(scoreArr); //4. 求出数组中 6 个分数的总和int sum = getSum(scoreArr); //5.(总和 - 最大值 - 最小值 )/4int avg = (sum - max - min) / (scoreArr.length - 2); //6.打印结果System.out.println("选手的最总得分为" + avg);}public static int getSum(int[] scoreArr) {int sum = 0;for (int i = 0; i < scoreArr.length; i++) {sum = sum + scoreArr[i];}return sum;}//求数组的最大值public static int getMax(int[] scoreArr) {int max = scoreArr[0];for (int i = 1; i < scoreArr.length; i++) {if (scoreArr[i] > max) {max = scoreArr[i];}}return max;}//求数组的最小值public static int getMin(int[] scoreArr) {int min = scoreArr[0];for (int i = 1; i < scoreArr.length; i++) {if (scoreArr[i] < min) {min = scoreArr[i];}}return min;}public static int[] getScores() {//定义数组int[] scores = new int[6];//使用键盘录入的形式,输入分数:0~100Scanner sc = new Scanner(System.in);for (int i = 0; i < scores.length; ) {System.out.println("请输入评委的打分");int score = sc.nextInt();if (score >= 0 && score <= 100) {scores[i] = score;i++;} else {System.out.println("成绩超出了范围,继续录入,当前的i为:" + i);}}return scores;} }
6.数字加密
public class 数字加密 {public static void main(String[] args) { /* 某系统的数字密码(大于 0)。比如 1983,采用加密方式进行传输,规则如下: 每位数加上 5 再对 10 求余 最后将所有数字反转 得到一串新数。 *///分析: //1.把整数里面的每一位放到数组当中int[] arr = {1, 9, 8, 3}; //2.加密 //每位数加上5for (int i = 0; i < arr.length; i++) {arr[i] = arr[i] + 5;} //再对10求余,for (int i = 0; i < arr.length; i++) {arr[i] = arr[i] % 10;} //将所有数字反转for (int i = 0, j = arr.length - 1; i < j; i++, j--) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;} //3.把数组里面的每一个数字进行拼接,变成加密之后的结果int number = 0;for (int i = 0; i < arr.length; i++) {number = number * 10 + arr[i];}System.out.println(number);} }
7.数字解密
public class 数字解密 {public static void main(String[] args) { /* 某系统的数字密码(大于 0)。比如 1983,采用加密方式进行传输, 规则如下: 每位数加上 5 再对 10 求余, 最后将所有数字反转, 得到一串新数。 按照以上规则进行解密: 比如 1983 加密之后变成 8346,解密之后变成 1983 */ //1. 定义数组记录解密之后的结果int[] arr = {8, 3, 4, 6}; //2. 反转for (int i = 0, j = arr.length - 1; i < j; i++, j--) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;} //3.由于加密是通过对10取余的方式进行获取的 //所以在解密的时候就需要判断,0~4之间+10 5~9数字不变for (int i = 0; i < arr.length; i++) {if (arr[i] >= 0 && arr[i] <= 4) {arr[i] = arr[i] + 10;}} //4.每一位减5for (int i = 0; i < arr.length; i++) {arr[i] = arr[i] - 5;} //5.获取数组里面的每一位数字拼接成最终的结果int number = 0;for (int i = 0; i < arr.length; i++) {number = number * 10 + arr[i];}System.out.println(number);} }
8.抢红包
import java.util.Random;public class 抢红包 {public static void main(String[] args) { /* 需求: 一个大 V 直播抽奖,奖品是现金红包,分别有 {2, 588, 888, 1000, 10000} 五个奖金。 请使用代码模拟抽奖,打印出每个奖项,奖项的出现顺序要随机且不重复。 打印效果如下:(随机顺序,不一定是下面的顺序) 888 元的奖金被抽出 588 元的奖金被抽出 10000 元的奖金被抽出 1000 元的奖金被抽出 2 元的奖金被抽出 *///分析: //1.定义数组表示奖池int[] arr = {2, 588, 888, 1000, 10000}; //2.定义新数组用于存储抽奖的结果int[] newArr = new int[arr.length]; //3.抽奖Random r = new Random(); //因为有5个奖项,所以这里要循环5次for (int i = 0; i < 5; ) {//获取随机索引int randomIndex = r.nextInt(arr.length);//获取奖项int prize = arr[randomIndex];//判断当前的奖项是否存在,如果存在则重新抽取,如果不存在,就表示是有效奖项boolean flag = contains(newArr, prize);if(!flag){//把当前抽取到的奖项添加到newArr当中newArr[i] = prize;//添加完毕之后,移动索引i++;}} //4.遍历newArrfor (int i = 0; i < newArr.length; i++) {System.out.println(newArr[i]);}} //判断prize在数组当中是否存在 //存在:true //不存在:falsepublic static boolean contains(int[] arr, int prize) {for (int i = 0; i < arr.length; i++) {if (arr[i] == prize) {return true;}}return false;} }
代码优化
import java.util.Random;public class 抢红包代码优化 {public static void main(String[] args) { /* 需求: 一个大 V 直播抽奖,奖品是现金红包,分别有 {2, 588, 888, 1000, 10000} 五个奖金。 请使用代码模拟抽奖,打印出每个奖项,奖项的出现顺序要随机且不重复。 打印效果如下:(随机顺序,不一定是下面的顺序) 888 元的奖金被抽出 588 元的奖金被抽出 10000 元的奖金被抽出 1000 元的奖金被抽出 2 元的奖金被抽出 *///1.把奖池里面的所有奖项打乱顺序int[] arr = {2, 588, 888, 1000, 10000};Random r = new Random();for (int i = 0; i < arr.length; i++) {//获取随机索引int randomIndex = r.nextInt(arr.length);//拿着i跟随机索引randomIndex上的值进行交换int temp = arr[i];arr[i] = arr[randomIndex];arr[randomIndex] = temp;} //2.遍历奖池,从0索引开始获取每一个奖项for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}} }
9.双色球彩票系统
import java.util.Random; import java.util.Scanner;public class 双色球彩票系统 {public static void main(String[] args) { //1.生成中奖号码int[] arr = createNumber(); //2.用户输入彩票号码(红球 + 蓝球)int[] userInputArr = userInputNumber(); //3.判断用户的中奖情况 //红球 蓝球int redCount = 0;int blueCount = 0;//判断红球for (int i = 0; i < userInputArr.length - 1; i++) {int redNumber = userInputArr[i];for (int j = 0; j < arr.length - 1; j++) {if (redNumber == arr[j]) {redCount++;//如果找到了,那么后面的数字就没有必要继续比较了//跳出内循环,继续判断下一个红球号码是否中奖break;}}}//判断蓝球int blueNumber = userInputArr[userInputArr.length - 1];if (blueNumber == arr[arr.length - 1]) {blueCount++;}//根据红球的个数以及蓝球的个数来判断中奖情况if(redCount == 6 && blueCount == 1){System.out.println("恭喜你,中奖1000万");}else if(redCount == 6 && blueCount == 0){System.out.println("恭喜你,中奖500万");}else if(redCount == 5 && blueCount == 1){System.out.println("恭喜你,中奖3000");}else if((redCount == 5 && blueCount == 0) || (redCount == 4 && blueCount == 1)){System.out.println("恭喜你,中奖200");}else if((redCount == 4 && blueCount == 0) || (redCount == 3 && blueCount == 1)){System.out.println("恭喜你,中奖10");}else if((redCount == 2 && blueCount == 1) || (redCount == 1 && blueCount == 1) || (redCount == 0 && blueCount == 1)){System.out.println("恭喜你,中奖5");}else{System.out.println("谢谢参与");}}public static int[] userInputNumber() {//1.创建数组用于添加用户购买的彩票号码//6个红球 1个蓝球 数组长度: 7int[] arr = new int[7];//2.利用键盘录入让用户输入Scanner sc = new Scanner(System.in);//让用户输入红球号码for (int i = 0; i < 6; ) {System.out.println("请输入第 " + (i + 1) + " 个红球号码");int redNumber = sc.nextInt();//redNumber在1~33 唯一不重复if (redNumber >= 1 && redNumber <= 33) {boolean flag = contains(arr, redNumber);if (!flag) {//不存在//有效的,可以添加到数组当中arr[i] = redNumber;i++;}} else {System.out.println("当前红球号码超出范围");}}//让用户输入蓝球号码System.out.println("请输入蓝球号码"); //1~16while (true) {int blueNumber = sc.nextInt();if (blueNumber >= 1 && blueNumber <= 16) {arr[arr.length - 1] = blueNumber;break;} else {System.out.println("当前蓝球号码超出范围");}}return arr;}public static int[] createNumber() {//1.创建数组用于添加中奖号码//6个红球 1个蓝球 数组长度: 7int[] arr = new int[7];//2.随机生成号码并添加到数组当中//红球: 不能重复的 1 2 3 4 5 6//蓝球: 可以跟红球号码重复 5//生成红球号码并添加到数组当中Random r = new Random();for (int i = 0; i < 6; ) {//获取红球号码int redNumber = r.nextInt(33) + 1;boolean flag = contains(arr, redNumber);if (!flag) {//把红球号码添加到数组当中arr[i] = redNumber;i++;}}//生成蓝球号码并添加到数组当中int blueNumber = r.nextInt(16) + 1;arr[arr.length - 1] = blueNumber;return arr;}//用于判断数字在数组中是否存在public static boolean contains(int[] arr, int number) {for (int i = 0; i < arr.length; i++) {if (arr[i] == number) {return true;}}return false;} }
10.二维数组
public class 二维数组 {public static void main(String[] args) { // 二维数组的静态初始化 // 格式:数据类型 [][] 数组名 = new 数据类型 [][]{{元素 1, 元素 2},{元素 1, 元素 2}}; // 范例:int [][] arr = new int [][]{{11,22},{33,44}}; // 简化格式:数据类型 [][] 数组名 = {{元素 1, 元素 2},{元素 1, 元素 2}}; // 范例:int [][] arr = {{11,22},{33,44}}; // 范例:int arr [][] = {{11,22},{33,44}};//1.二维数组静态初始化格式 //数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2},{元素1, 元素2}};int[][] arr1 = new int[][]{{1, 2, 3}, {4, 5, 6, 7, 8}};int[][] arr2 = {{1, 2, 3}, {4, 5, 6, 7, 8}}; //以后建议这样定义,把每一个一维数组,单独写成一行 //注意:每一个一维数组其实是二维数组中的元素,所以每一个一维数组之间需要用逗号隔开。最后一个一维数组后面不需要加逗号int[][] arr3 = {{1, 2, 3},{4, 5, 6, 7, 8}};//2.获取元素 //System.out.println(arr3[0]);//表示获取二维数组中的第一个一维数组 //arr3[0]:二维数组中的第一个一维数组 //arr3[0][0]:获取第一个一维数组中0索引的元素System.out.println(arr3[0][0]);//1//3、二维数组遍历 //外循环:遍历二维数组,得到里面的每一个一维数组for (int i = 0; i < arr3.length; i++) {//i: 表示二维数组中的每一个索引//arr3[i]: 表示二维数组中的每一个元素(一维数组)//内循环:遍历一维数组,得到里面的每一个元素for (int j = 0; j < arr3[i].length; j++) {//j:表示一维数组中的每一个元素System.out.print(arr3[i][j] + " ");}System.out.println();}// 二维数组的动态初始化 // 格式:数据类型 [][] 数组名 = new 数据类型 [m][n]; // m 表示这个二维数组,可以存放多少个一维数组 // n 表示每一个一维数组,可以存放多少个元素 // 范例:int [][] arr = new int [2][3]; // 该数组可以存放 2 个一维数组,每个一维数组中可以存放 3 个 int 类型元素//1.利用动态初始化格式创建二维数组 //3:表示二维数组长度为3,可以装3个一维数组 //5: 表示每一个一维数组的长度都是5,可以装5个int类型的元素int[][] arr = new int[3][5];//给二维数组赋值一个元素arr[0][0] = 10;//遍历二维数组 //外循环:遍历二维数组获取里面的每一个一维数组 //内循环:遍历一维数组获取每一个元素for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {System.out.print(arr[i][j] + " ");}System.out.println();}} }
面向对象
1.类和对象
类(设计图):是对象共同特征的描述 对象:是真实存在的具体东西 在 Java 中,必须先设计类,才能获得对象
创建一个类
public class Phone {//属性String brand;double price;//行为public void call(){System.out.println("手机在打电话");}public void playGame(){System.out.println("手机在玩游戏");} }
使用
// 如何得到类的对象 // 类名 对象名 = new 类名 (); // Phone p = new Phone();// 创建手机的对象Phone p = new Phone();// 如何使用对象 // 访问属性:对象名.成员变量 // 访问行为:对象名.方法名 (...)//给手机赋值p.brand = "小米";p.price = 1999.98;//获取手机对象中的值System.out.println(p.brand);System.out.println(p.price);//调用手机中的方法p.call();p.playGame();
定义类的补充注意事项 用来描述一类事物的类,专业叫做:Javabean 类。在 Javabean 类中,是不写 main 方法的 在以前,编写 main 方法的类,叫做测试类。我们可以在测试类中创建 javabean 类的对象并进行赋值调用
类名首字母建议大写,需要见名知意,驼峰模式。 一个 Java 文件中可以定义多个 class 类,且只能一个类是 public 修饰,而且 public 修饰的类名必须成为代码文件名。实际开发中建议还是一个文件定义一个 class 类。 成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值;一般无需指定初始化值,存在默认值。
2.封装
1. 什么是封装? 告诉我们,如何正确设计对象的属性和方法。 原则:对象代表什么,就得封装对应的的数据,并提供数据对应的行为 2. 理解封装思想的好处? 让编程变得很简单,有什么事,找对象,调方法就行。 降低我们的学习成本,可以少学、少记,或者说压根不用学,不用记对象有哪些方法,有需要时去找就行
private 关键字 是一个权限修饰符 可以修饰成员(成员变量和成员方法) 被 private 修饰的成员只能在本类中才能访问
public class GirlFriend {private String name;private int age;private String gender;//针对于每一个私有化的成员变量,都要提供get和set方法//set方法:给成员变量赋值//get方法:对外提供成员变量的值//作用:给成员变量name进行赋值public void setName(String n){name = n;}//作用:对外提供name属性public String getName(){return name;}public void setAge(int a){if(a >= 18 && a <= 50){age = a;}else{System.out.println("非法参数");}}public int getAge(){return age;}public void setGender(String g){gender = g;}public String getGender(){return gender;} }
//创建女朋友的对象GirlFriend gf1 = new GirlFriend(); //使用类中的方法赋值gf1.setName("小诗诗");gf1.setAge(18);gf1.setGender("女");System.out.println(gf1.getName());System.out.println(gf1.getAge());System.out.println(gf1.getGender());
3.就近原则和this关键字
public class GirlFriend2 {//属性private int age;//0 成员变量public void method() {int age = 10;//局部变量System.out.println(age);//10 只用age 就近原则System.out.println(this.age);//0} }
4.构造方法
构造方法概述构造方法也叫作构造器、构造函数。作用:在创建对象的时候给成员变量进行赋值的。构造方法的格式public class Student {修饰符 类名(参数) {方法体;}}特点:方法名与类名相同,大小写也要一致没有返回值类型,连 void 都没有没有具体的返回值(不能由 return 带回结果数据)执行时机:创建对象的时候由虚拟机调用,不能手动调用构造方法每创建一次对象,就会调用一次构造方法
public class Student {private String name;private int age;//如果我们自己没有写任何的构造方法 //那么虚拟机给我们加一个空参构造方法public Student(){System.out.println("看看我执行了吗?");} //带参构造public Student(String name,int age){this.name = name;this.age = age;}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;} }
//创建对象 //Student s = new Student(); //调用的空参构造// 带参构造Student s = new Student("zhangsan", 23);System.out.println(s.getName());System.out.println(s.getAge());
构造方法注意事项构造方法的定义如果没有定义构造方法,系统将给出一个默认的无参数构造方法如果定义了构造方法,系统将不再提供默认的构造方法构造方法的重载带参构造方法,和无参数构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载推荐的使用方式无论是否使用,都手动书写无参数构造方法,和带全部参数的构造方法
5.标准的javabean类
标准的 JavaBean 类 ① 类名需要见名知意 ② 成员变量使用 private 修饰 ③ 提供至少两个构造方法无参构造方法带全部参数的构造方法 ④ 成员方法提供每一个成员变量对应的 setXxx ()/getXxx ()如果还有其他行为,也需要写上
生成javabean类的快捷键:alt + insertalt + fn + insert
public class User {//属性private String username;private String password;private String email;private String gender;private int age;public User() {}public User(String username, String password, String email, String gender, int age) {this.username = username;this.password = password;this.email = email;this.gender = gender;this.age = age;}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 String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;} }
6.对象内存图
Student s = new Student();1.加载 class 文件2.申明局部变量3.在堆内存中开辟一个空间4.默认初始化5.显示初始化6.构造方法初始化7.将堆内存中的地址值赋值给左边的局部变量
7.基本数据类型和引用数据类型
从内存的角度去解释:基本数据类型:数据值是存储在自己的空间中特点:赋值给其他变量,也是赋的真实的值。引用数据类型:数据值是存储在其他空间中,自己空间中存储的是地址值。特点:赋值给其他变量,赋的地址值。
8.this的内存原理
this 的本质:所在方法调用者的地址值
9.成员变量和局部变量
成员变量和局部变量的区别区别 成员变量 局部变量类中位置不同 类中,方法外 方法内、方法申明上初始化值不同 有默认初始化值 没有,使用之前需要完成赋值内存位置不同 堆内存 栈内存生命周期不同 随着对象的创建而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的运行结束而消失作用域 整个类中有效 当前方法中有效
String name;//成员变量 public void study() {int i = 0;//局部变量System.out.println("好好学习"); } public void doHomework() {int j = 0;//局部变量System.out.println("多做练习"); } int age;//成员变量
面向对象综合训练
1.文字版格斗游戏
package 文字版格斗游戏.test2;import java.util.Random;public class Role {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 Role() {}public Role(String name, int blood,char gender) {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;}//定义一个方法用于攻击别人 //思考:谁攻击谁? //Role r1 = new Role(); //Role r2 = new Role(); //r1.攻击(r2); //方法的调用者去攻击参数public void attack(Role role) {Random r = new Random();int index = r.nextInt(attacks_desc.length);String KungFu = attacks_desc[index];//输出一个攻击的效果System.out.printf(KungFu,this.getName(),role.getName());System.out.println();//计算造成的伤害 1 ~ 20int hurt = r.nextInt(20) + 1;//剩余血量int remainBlood = role.getBlood() - hurt;//对剩余血量做一个验证,如果为负数了,就修改为0remainBlood = remainBlood < 0 ? 0 : remainBlood;//修改一下挨揍的人的血量role.setBlood(remainBlood);//受伤的描述//血量> 90 0索引的描述//80 ~ 90 1索引的描述//70 ~ 80 2索引的描述//60 ~ 70 3索引的描述//40 ~ 60 4索引的描述//20 ~ 40 5索引的描述//10 ~ 20 6索引的描述//小于10的 7索引的描述if (remainBlood > 90) {System.out.printf(injureds_desc[0], role.getName());} else if(remainBlood > 80 && remainBlood <= 90){System.out.printf(injureds_desc[1], role.getName());} else if(remainBlood > 70 && remainBlood <= 80){System.out.printf(injureds_desc[2], role.getName());} else if(remainBlood > 60 && remainBlood <= 70){System.out.printf(injureds_desc[3], role.getName());} else if(remainBlood > 40 && remainBlood <= 60){System.out.printf(injureds_desc[4], role.getName());} else if(remainBlood > 20 && remainBlood <= 40){System.out.printf(injureds_desc[5], role.getName());} else if(remainBlood > 10 && remainBlood <= 20){System.out.printf(injureds_desc[6], role.getName());} else{System.out.printf(injureds_desc[7], role.getName());}System.out.println();}public void showRoleInfo() {System.out.println("姓名为:" + getName());System.out.println("血量为:" + getBlood());System.out.println("性别为:" + getGender());System.out.println("长相为:" + getFace());}}
package 文字版格斗游戏.test2;public class GameTest {public static void main(String[] args) {//1.创建第一个角色Role r1 = new Role("乔峰", 100,'男');//2.创建第二个角色Role r2 = new Role("鸠摩智", 100,'男');//展示一下角色的信息r1.showRoleInfo();r2.showRoleInfo();//3.开始格斗 回合制游戏while(true){//r1开始攻击r2r1.attack(r2);//判断r2的剩余血量if(r2.getBlood() == 0){System.out.println(r1.getName() + " K.O了" + r2.getName());break;}//r2开始攻击r1r2.attack(r1);if(r1.getBlood() == 0){System.out.println(r2.getName() + " K.O了" + r1.getName());break;}}} }
2.两个对象数组练习
test1
package 两个对象数组练习.test1;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;} }
package 两个对象数组练习.test1;public class GoodsTest {public static void main(String[] args) { // 对象数组 1 // 定义数组存储 3 个商品对象。 // 商品的属性:商品的 id,名字,价格,库存。 // 创建三个商品对象,并把商品对象存入到数组当中。//1.创建一个数组Goods[] arr = new Goods[3];//2.创建三个商品对象Goods g1 = new Goods("001", "华为P40", 5999.0, 100);Goods g2 = new Goods("002", "保温杯", 227.0, 50);Goods g3 = new Goods("003", "枸杞", 12.7, 70);//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());}} }
键盘录入
键盘录入: 第一套体系: nextInt(); 接收整数 nextDouble();接收小数 next();接收字符串 遇到空格,制表符,回车就停止接受。这些符号后面的数据就不会接受了第二套体系: nextLine();接收字符串 可以接收空格,制表符,遇到回车才停止接受数据
Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数");int num1 = sc.nextInt();//输入 123 123System.out.println(num1);//123System.out.println("请输入第二个整数");int num2 = sc.nextInt();//不会让你输入 直接接收内存中剩余的123System.out.println(num2);//123
Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串");String line1 = sc.nextLine();//输入123 bcdSystem.out.println(line1);//输出123 bcdSystem.out.println("请输入第二个字符串");String line2 = sc.nextLine();System.out.println(line2);
//键盘录入的两套体系不能混用 //弊端:先用nextInt,再用nextLine会导致下面的nextLine接受不到数据Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数");int num = sc.nextInt();//输入123 + 回车System.out.println(num);//123 nextInt只接收到123 回车被下面的nextLine接收了System.out.println("请输入一个字符串");String line = sc.nextLine();System.out.println(line);
test2
package 两个对象数组练习.test2;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;} }
package 两个对象数组练习.test2;import java.util.Scanner;public class CarTest {public static void main(String[] args) { // 对象数组 2 // 定义数组存储 3 部汽车对象。 // 汽车的属性:品牌,价格,颜色。 // 创建三个汽车对象,数据通过键盘录入而来,并把数据存入到数组当中。//1.创建一个数组用来存3个汽车对象Car[] arr = new Car[3];//2.创建汽车对象,数据来自于键盘录入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());}} }
3.对象数组练习判断并统计
test1
package 对象数组练习判断并统计;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;} }
package 对象数组练习判断并统计;public class PhoneTest {public static void main(String[] args) { // 对象数组 3 // 定义数组存储 3 部手机对象。 // 手机的属性:品牌,价格,颜色。 // 要求,计算出三部手机的平均价格//1.创建一个数组Phone[] arr = new Phone[3];//2.创建手机的对象Phone p1 = new Phone("小米", 1999, "白色");Phone p2 = new Phone("华为", 4999, "蓝色");Phone p3 = new Phone("魅族", 3999, "红色");//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.求平均值//数据能不写死,尽量不写死//int avg = sum / arr.length;double avg2 = sum * 1.0 / arr.length;System.out.println(avg2);} }
test2
package 对象数组练习判断并统计.test2;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;} }
package 对象数组练习判断并统计.test2;public class GirlFriendTest {public static void main(String[] args) { //1.定义数组存入女朋友的对象GirlFriend[] arr = new GirlFriend[4];//2.创建女朋友对象GirlFriend gf1 = new GirlFriend("小涛涛", 18, "萌妹子", "吃零食");GirlFriend gf2 = new GirlFriend("小丹丹", 19, "萌妹子", "玩游戏");GirlFriend gf3 = new GirlFriend("小惠惠", 20, "萌妹子", "看书,学习");GirlFriend gf4 = new GirlFriend("小莉莉", 21, "憨妹子", "睡觉");//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++) {//i 索引 arr[i] 元素(女朋友对象)GirlFriend gf = arr[i];//累加sum = 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 + "个");} }
4.复杂对象数组练习
package 复杂对象数组练习;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;} }
package 复杂对象数组练习;public class Test {public static void main(String[] args) { // 对象数组 5 // 定义一个长度为 3 的数组,数组存储 1~3 名学生对象作为初始数据,学生对象的学号,姓名各不相同。 // 学生的属性:学号,姓名,年龄。 // 要求 1:再次添加一个学生对象,并在添加的时候进行学号的唯一性判断。 // 要求 2:添加完毕之后,遍历所有学生信息。 // 要求 3:通过 id 删除学生信息 // 如果存在,则删除,如果不存在,则提示删除失败。 // 要求 4:删除完毕之后,遍历所有学生信息。 // 要求 5:查询数组 id 为 “2” 的学生,如果存在,则将他的年龄 + 1 岁//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;//要求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(newArr);}else{//没有存满//[stu1,stu2,null]//getCount获取到的是2,表示数组当中已经有了2个元素//还有一层意思:如果下一次要添加数据,就是添加到2索引的位置arr[count] = stu4;//要求2:添加完毕之后,遍历所有学生信息。printArr(arr);}}/*要求3:通过id删除学生信息 如果存在,则删除,如果不存在,则提示删除失败。*/ //要找到id在数组中对应的索引int index = getIndex(arr, 4);if (index >= 0){//如果存在,则删除arr[index] = null;//遍历数组printArr(arr);}else{//如果不存在,则提示删除失败System.out.println("当前id不存在,删除失败");}//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());}}}//创建一个新的数组,长度 = 老数组的长度 + 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) {for (int i = 0; i < arr.length; i++) {//依次获取到数组里面的每一个学生对象Student stu = arr[i];if(stu != null){//获取数组中学生对象的idint sid = stu.getId();//比较if(sid == id){return true;}}}//当循环结束之后,还没有找到一样的,那么就表示数组中要查找的id是不存在的。return false;} }
字符串
1.API和API帮助文档
API 和 API 帮助文档API:目前是 JDK 中提供的各种功能的 Java 类。这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。API 帮助文档:帮助开发人员更好的使用 API 和查询 API 的一个工具。
2.String概述
String 的注意点字符串的内容是不会发生改变的,它的对象在创建后不能被更改。Strin 是 Java 定义好的一个类。定义在 java.lang 包中,所以使用的时候不需要导包。Java 程序中的所有字符串文字(例如 “abcdefg” )都被实为此类的对象。字符串不可变,它们的值在创建后不能被更改
3.String构造方法代码实现和内存分析
使用直接赋值的方式获取一个字符串对象
String s1 = "abc"; System.out.println(s1);//abc
使用new的方式来获取一个字符串对象 空参构造:可以获取一个空白的字符串对象
String s2 = new String(); System.out.println("@" + s2 + "!");//""
传递一个字符串,根据传递的字符串内容再创建一个新的字符串对象
String s3 = new String("abc"); System.out.println(s3);
传递一个字符数组,根据字符数组的内容再创建一个新的字符串对象 需求:我要修改字符串的内容。 abc Qbc abc --> {'a','b','c'} --> {'Q','b','c'} --> "Qbc"
char[] chs = {'a','b','c','d'}; String s4 = new String(chs); System.out.println(s4);//abcd
传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象 应用场景:以后在网络当中传输的数据其实都是字节信息 我们一般要把字节信息进行转换,转成字符串,此时就要用到这个构造了。
byte[] bytes = {97, 98, 99, 100}; String s5 = new String(bytes); System.out.println(s5);//abcd
当使用双引号直接赋值时,系统会检查该字符串在串池中是否存在。不存在:创建新的存在:复用
4.字符串的比较
== 号比的到底是什么?
// 基本数据类型int a = 10;int b = 20;System.out.println(a == b); //false // 基本数据类型比较的是数据值
// 引用数据类型String s1 = new String("abc");String s2 = new String("abc");System.out.println(s1 == s2); //false // 引用数据类型比较的是地址值
字符串比较boolean equals 方法 (要比较的字符串):完全一样结果才是 true,否则为 falseboolean equalsIgnoreCase (要比较的字符串):忽略大小写的比较
//创建两个字符串对象String s3 = new String("abc");String s4 = "Abc";//比较字符串对象中的内容是否相等boolean result1 = s3.equals(s4);System.out.println(result1);//false//比较字符串对象中的内容是否相等,忽略大小写boolean result2 = s3.equalsIgnoreCase(s4);System.out.println(result2);//true
5.练习用户登录
import java.util.Scanner;public class 练习用户登录 {// 需求:已知正确的用户名和密码,请用程序实现模拟用户登录。// 总共给三次机会,登录之后,给出相应的提示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++) { // 0 1 2System.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 + "被锁定,请联系黑马程序员官方客服小姐姐:XXXX-XXXXX");}else{System.out.println("用户登录失败,用户名或密码有误,您还剩下" + (2 - i) + "次机会");//2 1 0}}}} }
6.练习遍历字符串和统计字符个数
public char charAt (int index):根据索引返回字符public int length ():返回此字符串的长度数组的长度:数组名.length字符串的长度:字符串对象.length ()
// 需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串//1.键盘录入一个字符串Scanner sc = new Scanner(System.in);System.out.println("请输入一个字符串");String str = sc.next(); //2.进行遍历for (int i = 0; i < str.length(); i++) {//i 依次表示字符串的每一个索引char c = str.charAt(i);System.out.println(c);
// 统计字符次数 // 键盘录入一个字符串,统计该字符串中大写字母字符,小写字母字符,数字字符出现的次数(不考虑其他字符)//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++;}} //3.输出打印System.out.println("小写字母有: " + smallCount + "个");System.out.println("大写字母有: " + bigCount + "个");System.out.println("数字字母有: " + numberCount + "个");
7.练习字符串拼接和反转
public class 练习字符串拼接和反转 {public static void main(String[] args) { // 定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回,调用该方法,并在控制台输出结果。 // 例如: // 数组为 int [] arr = {1,2,3}; // 执行方法后的输出结果为:[1, 2, 3]int[] arr = {1, 2, 3};String str = arrToString(arr);System.out.println(str);//[1, 2, 3]// 字符串反转 // 定义一个方法,实现字符串反转。 // 键盘录入一个字符串,调用该方法后,在控制台输出结果。 // 例如,键盘录入 abc,输出结果 cbaString result = reverser("abc");System.out.println(result);//cba}//1. 我要干嘛? --- 遍历数组并把数组拼接成一个字符串 //2. 我干这件事情需要什么才能完成? --- 数组 //3. 我干完了是否要把结果返回给调用处 --- 返回一个拼接之后的字符串 // 如果调用处需要继续使用,那么必须返回 // 如果调用处不需要继续使用,那么可以返回也可以不返回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++) {//i 索引 arr[i] 元素if (i == arr.length - 1) {result = result + arr[i];} else {result = result + arr[i] + ", ";}}//此时拼接右括号result = result + "]";return result;}//1.我要干嘛? --- 字符串的反转 //2.我干这件事情,需要什么才能完成? --- 需要一个字符串 //3.调用处是否需要继续使用方法的结果呢? ---需要结果进行输出public static String reverser(String str){String result = "";for (int i = str.length() - 1; i >= 0; i--) {//i 依次表示字符串中的每一个索引(倒着的)char c = str.charAt(i);result = result + c;}return result;} }
8.练习金额转换
import java.util.Scanner;public class 练习金额转换 {public static void main(String[] args) {//1.键盘录入一个金额Scanner sc = new Scanner(System.in);int money;while (true) {System.out.println("请录入一个金额");money = sc.nextInt();if(money >= 0 && money <= 9999999){break;}else{System.out.println("金额无效");}}//定义一个变量用来表示钱的大写String moneyStr = "";//2.得到money里面的每一位数字,再转成中文while (true) { //2135//从右往左获取数据,因为右侧是数据的个位int ge = money % 10;String capitalNumber = getCapitalNumber(ge);//把转换之后的大写拼接到moneyStr当中moneyStr = capitalNumber + moneyStr;//第一次循环 : "伍" + "" = "伍"//第二次循环 : "叁" + "伍" = "叁伍"//去掉刚刚获取的数据money = money / 10;//如果数字上的每一位全部获取到了,那么money记录的就是0,此时循环结束if (money == 0) {break;}}//3.在前面补0,补齐7位int count = 7 - moneyStr.length();for (int i = 0; i < count; i++) {moneyStr = "零" + moneyStr;}System.out.println(moneyStr);//4.插入单位//定义一个数组表示单位String[] arr = {"佰","拾","万","仟","佰","拾","元"};// 零 零 零 贰 壹 叁 伍//遍历moneyStr,依次得到 零 零 零 贰 壹 叁 伍//然后把arr的单位插入进去String result = "";for (int i = 0; i < moneyStr.length(); i++) {char c = moneyStr.charAt(i);//把大写数字和单位拼接到result当中result = result + c + arr[i];}//5.打印最终结果System.out.println(result);}//定义一个方法把数字变成大写的中文 //1 -- 壹public static String getCapitalNumber(int number){//定义数组,让数字跟大写的中文产生一个对应关系String[] arr = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};//返回结果return arr[number];}}
9.练习手机号屏蔽
String substring (int beginIndex, int endIndex) 截取注意点:包头不包尾,包左不包右只有返回值才是截取的小串String substring (int beginIndex) 截取到末尾
//1.获取一个手机号码String phoneNumber = "13112349468"; //2.截取手机号码前面三位String start = phoneNumber.substring(0, 3); //3.截取手机号码后面四位String end = phoneNumber.substring(7); //4.拼接String result = start + "****" + end; //5.打印System.out.println(result);//131****9468
10.练习身份证号码信息查看
public class 练习身份证号码信息查看 {public static void main(String[] args) { //1.定义一个字符串记录身份证号码String id = "321281202001011234"; //2.获取出生年月日String year = id.substring(6, 10);String month = id.substring(10, 12);String day = id.substring(12, 14);System.out.println("人物信息为: ");System.out.println("出生年月日:" + year + "年" + month + "月" + day + "日");//3.获取性别char gender = id.charAt(16);//'3' ---> 3 //利用ASCII码表进行转换 //'0' ---> 48 //'1' ---> 49 //'2' ---> 50 //'3' ---> 51 //'4' ---> 52 //'5' ---> 53 //'6' ---> 54 //'7' ---> 55 //'8' ---> 56 //'9' ---> 57int num = gender - 48;if(num % 2 == 0){System.out.println("性别为:女");}else{System.out.println("性别为:男");}} }
11.练习敏感词替换
String replace (旧值,新值) 替换注意点:只有返回值才是替换之后的结果
public class 练习敏感词替换 {public static void main(String[] args) { // String replace (旧值,新值) 替换 // 注意点:只有返回值才是替换之后的结果//1.获取到说的话String talk = "你玩的真好,以后不要再玩了,TMD,CNM";//2.定义一个敏感词库String[] arr = {"TMD","CNM","SB","MLGB"};//3.循环得到数组中的每一个敏感词,依次进行替换for (int i = 0; i < arr.length; i++) {talk = talk.replace(arr[i], "***");} //4.打印结果System.out.println(talk);} }
12.StringBuilder的基本操作
StringBuilder 概述StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的作用:提高字符串的操作效率
StringBuilder 构造方法方法名 说明public StringBuilder() 创建一个空白可变字符串对象,不含有任何内容public StringBuilder(String str) 根据字符串的内容,来创建可变字符串对象
StringBuilder 常用方法方法名 说明public StringBuilder append (任意类型) 添加数据,并返回对象本身public StringBuilder reverse() 反转容器中的内容public int length() 返回长度(字符出现的个数)public String toString() 通过 toString () 就可以实现把 StringBuilder 转换为 String
//1.创建对象StringBuilder sb = new StringBuilder("abc");//2.添加元素sb.append(1);sb.append(2.3);sb.append(true);//反转sb.reverse(); //获取长度int len = sb.length();System.out.println(len);//打印 //普及: //因为StringBuilder是Java已经写好的类 //java在底层对他做了一些特殊处理。 //打印对象不是地址值而是属性值。System.out.println(sb);//abc
//1.创建对象StringBuilder sb = new StringBuilder();//StringBuilder是个容器 //2.添加字符串sb.append("aaa").append("bbb").append("ccc").append("ddd");System.out.println(sb);//aaabbbcccddd//3.再把StringBuilder变回字符串String str = sb.toString();System.out.println(str);//aaabbbcccddd
13.练习StringBuilder对称字符串
使用StringBuilder的场景: 1.字符串的拼接 2.字符串的反转
import java.util.Scanner;public class 练习StringBuilder对称字符串 {public static void main(String[] args) { // 对称字符串 // 需求:键盘接受一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是 // 对称字符串:123321、111 // 非对称字符串:123123//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("当前字符串不是对称字符串");}} }
14.练习StringBuilder拼接字符串
public class 练习StringBuilder拼接字符串 {public static void main(String[] args) { // 拼接字符串 // 需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。调用该方法,并在控制台输出结果。 // 例如:数组为 int [] arr = {1,2,3}; // 执行方法后的输出结果为:[1, 2, 3]//1.定义数组int[] arr = {1, 2, 3};//2.调用方法把数组变成字符串String str = arrToString(arr);System.out.println(str);}public static String arrToString(int[] arr) {StringBuilder 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();} }
15.Stringjoiner
StringJoiner 概述StringJoiner 跟 StringBuilder 一样,也可以看成是一个容器,创建之后里面的内容是可变的。作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。JDK8 出现的
StringJoiner 的构造方法方法名 说明public StringJoiner (间隔符号) 创建一个 StringJoiner 对象,指定拼接时的间隔符号public StringJoiner (间隔符号,开始符号,结束符号) 创建一个 StringJoiner 对象,指定拼接时的间隔符号、开始符号、结束符号
StringJoiner 的成员方法方法名 说明public StringJoiner add (添加的内容) 添加数据,并返回对象本身public int length() 返回长度(字符出现的个数)public String toString() 返回一个字符串(该字符串就是拼接之后的结果)
//1.创建一个对象,并指定中间的间隔符号 StringJoiner sj1 = new StringJoiner("---"); //2.添加元素 sj1.add("aaa").add("bbb").add("ccc"); //3.打印结果 System.out.println(sj1);//aaa---bbb---ccc
//1.创建对象StringJoiner sj2 = new StringJoiner(",", "[", "]"); //2.添加元素sj2.add("aaa").add("bbb").add("ccc");int len = sj2.length();System.out.println(len);//15//3.打印System.out.println(sj2);//[aaa, bbb, ccc]String str = sj2.toString();System.out.println(str);//[aaa, bbb, ccc]
16.字符串相关类的底层原理
扩展底层原理 1:字符串存储的内存原理直接赋值会复用字符串常量池中的new 出来不会复用,而是开辟一个新的空间
扩展底层原理 2:== 号比较的到底是什么?基本数据类型比较数据值引用数据类型比较地址值
扩展底层原理 3:字符串拼接的底层原理拼接的时候没有变量,都是字符串。触发字符串的优化机制。在编译的时候就已经是最终的结果了。如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。字符串拼接的时候,如果有变量:JDK8 以前:系统底层会自动创建一个 StringBuilder 对象,然后再调用其 append 方法完成拼接。拼接后,再调用其 toString 方法转换为 String 类型,而 toString 方法的底层是直接 new 了一个字符串对象。JDK8 版本:系统会预估算字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。字符串拼接的时候有变量参与:在内存中创建了很多对象浪费空间,时间也非常慢结论:如果很多字符串变量拼接,不要直接 +。在底层会创建多个对象,浪费时间,浪费性能。
扩展底层原理 4:StringBuilder 提高效率原理图所有要拼接的内容都会往 StringBuilder 中放,不会创建很多无用的空间,节约内存
扩展底层原理 5:StringBuilder 源码分析默认创建一个长度为 16 的字节数组添加的内容长度小于 16,直接存添加的内容大于 16 会扩容(原来的容量 * 2+2)如果扩容之后还不够,以实际长度为准
StringBuilder sb = new StringBuilder(); //容量:最多装多少 System.out.println(sb.capacity());//16 //长度:已经装了多少 System.out.println(sb.length());//0
sb.append("abcdefghijklmnopqrstuvwxyz");System.out.println(sb.capacity());//34System.out.println(sb.length());//26
sb.append("abcdefghijklmnopqrstuvwxyz0123456789"); System.out.println(sb.capacity());//36 System.out.println(sb.length());//36
17.较难练习转换罗马数字
转换罗马数字键盘录入一个字符串,要求 1:长度为小于等于 9要求 2:只能是数字将内容变成罗马数字下面是阿拉伯数字跟罗马数字的对比关系:I - 1、II - 2、III - 3、IV - 4、V - 5、VI - 6、VII - 7、VIII - 8、IX - 9注意点:罗马数字里面是没有 0 的如果键盘录入的数字包含 0,可以变成 “”(长度为 0 的字符串)
import java.util.Scanner;public class 较难练习转换罗马数字 {public static void main(String[] args) { //1.键盘录入一个字符串 //书写Scanner的代码Scanner sc = new Scanner(System.in);String str;while (true) {System.out.println("请输入一个字符串");str = sc.next();//2.校验字符串是否满足规则boolean flag = checkStr(str);if (flag) {break;} else {System.out.println("当前的字符串不符合规则,请重新输入");continue;}} //查表法:数字跟数据产生一个对应关系 // StringBuilder sb = new StringBuilder(); // for (int i = 0; i < str.length(); i++) { // char c = str.charAt(i); // int number = c - 48; // 1 2 3 4 5 // String s = changeLuoMa(number); // sb.append(s); // } // System.out.println(sb);StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);String s = changeLuoMa(c);sb.append(s);}System.out.println(sb);} // public static String changeLuoMa(int number) { // //定义一个数组,让索引跟罗马数字产生一个对应关系 // String[] arr = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; // return arr[number]; // }// 利用switch进行匹配public static String changeLuoMa(char number) {String str = switch (number) {case '0' -> "";case '1' -> "Ⅰ";case '2' -> "Ⅱ";case '3' -> "Ⅲ";case '4' -> "Ⅳ";case '5' -> "Ⅴ";case '6' -> "Ⅵ";case '7' -> "Ⅶ";case '8' -> "Ⅷ";case '9' -> "Ⅸ";default -> "";};return str;}public static boolean checkStr(String str) {//123456//要求1:长度为小于等于9if (str.length() > 9) {return false;}//要求2:只能是数字for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);//0~9if (c < '0' || c > '9') {return false;}}//只有当字符串里面所有的字符全都判断完毕了,我才能认为当前的字符串是符合规则return true;} }
18.较难练习调整字符串
调整字符串给定两个字符串,A 和 B。A 的旋转操作就是将 A 最左边的字符移动到最右边。例如,若 A = 'abcde',在移动一次之后结果就是 'bcdea'。如果在若干次调整操作之后,A 能变成 B,那么返回 True。如果不能匹配成功,则返回 false
public class 较难练习调整字符串 {public static void main(String[] args) { //1.定义两个字符串String strA = "abcde";String strB = "cdeab"; //2.调用方法进行比较boolean result = check(strA, strB); //3.输出System.out.println(result);}public static boolean check(String strA, String strB) {for (int i = 0; i < strA.length(); i++) {strA = rotate(strA);if(strA.equals(strB)){return true;}}//所有的情况都比较完毕了,还不一样那么直接返回falsereturn false;}//作用:旋转字符串,把左侧的字符移动到右侧去 //形参:旋转前的字符串 //返回值:旋转后的字符串public static String rotate(String str){//套路://如果我们看到要修改字符串的内容//可以有两个办法://1.用subString进行截取,把左边的字符截取出来拼接到右侧去//2.可以把字符串先变成一个字符数组,然后调整字符数组里面数据,最后再把字符数组变成字符串。// //1.截取思路 // //获取最左侧那个字符 // char first = str.charAt(0); // //获取剩余的字符 // String end = str.substring(1); // return end + first;//2.数组思路 // toCharArray方法: // "ABC" 变为 ['A','B','C'];char[] arr = str.toCharArray(); //拿到0索引上的字符char first = arr[0]; //把剩余的字符依次往前挪一个位置for (int i = 1; i < arr.length; i++) {arr[i - 1] = arr[i];} //把原来0索引上的字符放到最后一个索引arr[arr.length - 1] = first; //利用字符数组创建一个字符串对象String result = new String(arr);return result;} }
ArrayList
1.集合的基本使用
集合和数组的对比数组:长度固定可以存基本数据类型可以存引用数据类型集合:长度可变可以存引用数据类型基本数据类型 需要变为 包装类 再存
//1.创建集合的对象 //泛型:限定集合中存储数据的类型 //JDK7前: //ArrayList<String> list = new ArrayList<String>(); //JDK7后: //ArrayList<String> list = new ArrayList<>();//此时我们创建的是ArrayList的对象,而ArrayList是java已经写好的一个类 //这个类在底层做了一些处理 //打印对象不是地址值,而是集合中存储数据内容 //在展示的时候会拿[]把所有的数据进行包裹ArrayList<String> list = new ArrayList<>();System.out.println(list);//[]
2.ArrayList 成员方法方法名 说明增 boolean add(E e) 添加元素,返回值表示是否添加成功删 boolean remove(E e) 删除指定元素,返回值表示是否删除成功E remove(int index) 删除指定索引的元素,返回被删除元素改 E set(int index,E e) 修改指定索引下的元素,返回原来的元素查 E get(int index) 获取指定索引的元素int size() 集合的长度,也就是集合中元素的个数
//添加元素 list.add("aaa"); list.add("aaa"); list.add("bbb"); list.add("ccc");
//删除元素 boolean result1 = list.remove("aaa"); System.out.println(result1);//true boolean result2 = list.remove("ddd"); System.out.println(result2);//false System.out.println(list);//[aaa, bbb, ccc]String str = list.remove(0); System.out.println(str);//aaa System.out.println(list);//[bbb, ccc]
//修改元素 String result = list.set(1, "ddd"); System.out.println(result);//ccc System.out.println(list);//[bbb, ddd]
//查询元素 String s = list.get(0); System.out.println(s);//bbb System.out.println(list);//[bbb, ddd]
for (int i = 0; i < list.size(); i++) {//i 索引//list.get(i) 元素String str1 = list.get(i);System.out.println(str1);
2.添加字符串和数字并遍历
// 集合的遍历方式 // 需求:定义一个集合,添加字符串,并进行遍历 // 遍历格式参照:[元素 1, 元素 2, 元素 3]。//1.创建集合ArrayList<String> list = new ArrayList<>(); //2.添加元素list.add("点赞了吗?");list.add("收藏了吗?");list.add("投币了吗?");list.add("转发了吗?"); //3.遍历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("]");
添加数字并遍历需求:定义一个集合,添加数字,并进行遍历。遍历格式参照:[元素 1, 元素 2, 元素 3]。基本数据类型对应的包装类byte Byteshort Shortchar Characterint Integerlong Longfloat Floatdouble Doubleboolean Boolean
//1.创建集合ArrayList<Integer> list = new ArrayList<>(); //2.添加元素 //jdk5以后 int Integer 之间是可以互相转化的list.add(1);list.add(2);list.add(3);list.add(4);list.add(5); //3.遍历集合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("]");
3.练习添加学生对象并遍历
import java.util.ArrayList;public class 练习添加学生对象并遍历 {public static void main(String[] args) { // 添加学生对象并遍历 // 需求:定义一个集合,添加一些学生对象,并进行遍历 // 学生类的属性为:姓名,年龄。//1.创建集合ArrayList<Student> list = new ArrayList<>(); //2.创建学生对象Student s1 = new Student("zhangsan", 23);Student s2 = new Student("lisi", 24);Student s3 = new Student("wangwu", 25); //3.添加元素list.add(s1);list.add(s2);list.add(s3); //4.遍历集合for (int i = 0; i < list.size(); i++) {//i 索引 list.get(i) 元素/学生对象Student stu = list.get(i);System.out.println(stu.getName() + ", " + stu.getAge());}} }
4.练习键盘添加学生对象并遍历
import java.util.ArrayList; import java.util.Scanner;public class 练习键盘添加学生对象并遍历 {public static void main(String[] args) { //1.创建集合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);}//3.遍历for (int i = 0; i < list.size(); i++) {//i 索引 list.get(i) 元素/学生对象Student stu = list.get(i);System.out.println(stu.getName() + ", " + stu.getAge());}} }
5.练习查找用户是否存在
import java.util.ArrayList;public class 练习查找用户是否存在 {public static void main(String[] args) { // 添加用户对象并判断是否存在 // 需求: // main 方法中定义一个集合,存入三个用户对象。 // 用户属性为:id,username,password // 要求:定义一个方法,根据 id 查找对应的用户信息。 // 如果存在,返回 索引 // 如果不存在,返回 -1//1.创建集合ArrayList<User> list = new ArrayList<>(); //2.创建三个用户对象User u1 = new User("heima001", "zhangsan", "123456");User u2 = new User("heima002", "lisi", "12345678");User u3 = new User("heima003", "wangwu", "1234qwer");//3.把用户对象添加到集合当中list.add(u1);list.add(u2);list.add(u3);//4.查找索引int index = getIndex(list, "heima001"); //5.打印System.out.println(index);}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;} }
6.练习返回多个数据
import java.util.ArrayList;public class 练习返回多个数据 {public static void main(String[] args) { // 添加手机对象并返回要求的数据 // 需求: // 定义 Javabean 类:Phone // Phone 属性:品牌,价格。 // main 方法中定义一个集合,存入三个手机对象。 // 分别为:小米,1000。苹果,8000。锤子 2999。 // 定义一个方法,将价格低于 3000 的手机信息返回。//1.创建集合对象ArrayList<Phone> list = new ArrayList<>(); //2.创建手机的对象Phone p1 = new Phone("小米", 1000);Phone p2 = new Phone("苹果", 8000);Phone p3 = new Phone("锤子", 2999); //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,那么就把手机对象添加到resultList中if(price < 3000){resultList.add(p);}}//返回resultListreturn resultList;} }
学生管理系统
import java.util.ArrayList; import java.util.Scanner;public class StudentSystem {public static void main(String[] args) {ArrayList<Student> list = new ArrayList<>(); // 给循环起名为looploop: 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("请输入您的选择:");Scanner sc = new Scanner(System.in);String choose = sc.next();switch (choose) {case "1" -> addStudent(list);case "2" -> deleteStudent(list);case "3" -> updateStudent(list);case "4" -> queryStudent(list);case "5" -> {System.out.println("退出"); // break loop; //退出叫做loop的循环System.exit(0); //停止虚拟机运行}default -> System.out.println("没有这个选项");}}}//添加学生public static void addStudent(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){//表示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("学生信息添加成功");}//删除学生public static void deleteStudent(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 updateStudent(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("请输入要修改的学生年龄");int newAge = sc.nextInt();stu.setAge(newAge);System.out.println("请输入要修改的学生家庭住址");String newAddress = sc.next();stu.setAddress(newAddress);System.out.println("学生信息修改成功");}//查询学生public static void queryStudent(ArrayList<Student> list){if(list.size() == 0){System.out.println("当前无学生信息,请添加后再查询");//结束方法return;}//打印表头信息System.out.println("id\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;}}//当循环结束之后还没有找到,就表示不存在,返回-1.return -1;} }
学生管理系统升级
import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class APP {public static void main(String[] args) {ArrayList<User> list = new ArrayList<>();Scanner sc = new Scanner(System.in);while (true) {System.out.println("欢迎来到学生管理系统");System.out.println("请选择操作:1登录 2注册 3忘记密码");String choose = sc.next();switch (choose) {case "1" -> login(list);case "2" -> register(list);case "3" -> forgetPassword(list);case "4" -> {System.out.println("谢谢使用,再见");System.exit(0);}default -> System.out.println("没有这个选项");}}}private static void login(ArrayList<User> list) {Scanner sc = new Scanner(System.in);for (int i = 0; i < 3; i++) {System.out.println("请输入用户名");String username = sc.next();//判断用户名是否存在boolean flag = contains(list, username);if (!flag) {System.out.println("用户名" + username + "未注册,请先注册再登录");return;}System.out.println("请输入密码");String password = sc.next();while (true) {String rightCode = getCode();System.out.println("当前正确的验证码为: " + rightCode);System.out.println("请输入验证码");String code = sc.next();if(code.equalsIgnoreCase(rightCode)){System.out.println("验证码正确");break;}else{System.out.println("验证码错误");continue;}}//验证用户名和密码是否正确 //集合中是否包含用户名和密码 //定义一个方法验证用户名和密码是否正确//封装思想的应用: //我们可以把一些零散的数据,封装成一个对象 //以后传递参数的时候,只要传递一个整体就可以了,不需要管这些零散的数据。User useInfo = new User(username, password, null, null);boolean result = checkUserInfo(list, useInfo);if (result) {System.out.println("登录成功,可以开始使用学生管理系统了");//创建对象调用方法,启动学生管理系统StudentSystem ss = new StudentSystem();ss.startStudentSystem();break;} else {System.out.println("登录失败,用户名或密码错误");if (i == 2) {System.out.println("当前账号" + username + "被锁定,请联系黑马程序员客服: XXX-XXXXX");//当前账号锁定之后,直接结束方法即可return;} else {System.out.println("用户名或密码错误,还剩下" + (2 - i) + "次机会");}}}}private static boolean checkUserInfo(ArrayList<User> list, User useInfo) {//遍历集合,判断用户是否存在,如果存在登录成功,如果不存在登录失败for (int i = 0; i < list.size(); i++) {User user = list.get(i);if (user.getUsername().equals(useInfo.getUsername()) && user.getPassword().equals(useInfo.getPassword())) {return true;}}return false;}private static void forgetPassword(ArrayList<User> list) {Scanner sc = new Scanner(System.in);System.out.println("请输入用户名");String username = sc.next();boolean flag = contains(list, username);if(!flag){System.out.println("当前用户" + username + "未注册,请先注册");return;}//键盘录入身份证号码和手机号码System.out.println("请输入身份证号码");String personID = sc.next();System.out.println("请输入手机号码");String phoneNumber = sc.next();//需要把用户对象通过索引先获取出来。int index = findIndex(list, username);User user = list.get(index);//比较用户对象中的手机号码和身份证号码是否相同if(!(user.getPersonID().equalsIgnoreCase(personID) && user.getPhoneNumber().equals(phoneNumber))){System.out.println("身份证号码或手机号码输入有误,不能修改密码");return;}//当代码执行到这里,表示所有的数据全部验证成功,直接修改即可String password;while (true) {System.out.println("请输入新的密码");password = sc.next();System.out.println("请再次输入新的密码");String againPassword = sc.next();if(password.equals(againPassword)){System.out.println("两次密码输入一致");break;}else{System.out.println("两次密码输入不一致,请重新输入");continue;}}//直接修改即可user.setPassword(password);System.out.println("密码修改成功");}private static int findIndex(ArrayList<User> list, String username) {for (int i = 0; i < list.size(); i++) {User user = list.get(i);if(user.getUsername().equals(username)){return i;}}return -1;}private static void register(ArrayList<User> list) {//用户名,密码,身份证号码,手机号码放到用户对象中//把用户对象添加到集合中//1.键盘录入用户名Scanner sc = new Scanner(System.in);String username;while (true) {System.out.println("请输入用户名");username = sc.next();//开发细节:先验证格式是否正确,再验证是否唯一// 因为在以后所有的数据,都是存在数据库中,如果我们要校验,需要使用到网络资源。boolean flag1 = checkUsername(username);if(!flag1){System.out.println("用户名格式不满足条件,需要重新输入");continue;}//校验用户名唯一//username到集合中判断是否有存在boolean flag2 = contains(list,username);if(flag2){//用户名已存在,那么当前用户名无法注册,需要重新输入System.out.println("用户名" + username + "已存在,请重新输入");}else{//不存在,表示当前用户名可用,可以继续录入下面的其他数据System.out.println("用户名" + username + "可用");break;}}//2.键盘录入密码//密码键盘输入两次,两次一致才可以进行注册。String password;while (true) {System.out.println("请输入要注册的密码");password = sc.next();System.out.println("请再次输入要注册的密码");String againPassword = sc.next();if(!password.equals(againPassword)){System.out.println("两次密码输入不一致,请重新输入");continue;}else{System.out.println("两次密码一致,继续录入其他数据");break;}}//3.键盘录入身份证号码String personID;while (true) {System.out.println("请输入身份证号码");personID = sc.next();boolean flag = checkPersonID(personID);if(flag){System.out.println("身份证号码满足要求");break;}else{System.out.println("身份证号码格式有误,请重新输入");continue;}}//4.键盘录入手机号码String phoneNumber;while (true) {System.out.println("请输入手机号码");phoneNumber = sc.next();boolean flag = checkPhoneNumber(phoneNumber);if(flag){System.out.println("手机号码格式正确");break;}else{System.out.println("手机号码格式有误,请重新输入");continue;}}//用户名,密码,身份证号码,手机号码放到用户对象中User u = new User(username, password, personID, phoneNumber); //把用户对象添加到集合中list.add(u);System.out.println("注册成功"); //遍历集合printList(list);}private static void printList(ArrayList<User> list) {for (int i = 0; i < list.size(); i++) {//i 索引User user = list.get(i);System.out.println(user.getUsername() + ", " + user.getPassword() + ", "+ user.getPersonID() + ", " + user.getPhoneNumber());}}private static boolean checkPhoneNumber(String phoneNumber) {//长度为11位if (phoneNumber.length() != 11) {return false;}//不能以0为开头if (phoneNumber.startsWith("0")) {return false;}//必须都是数字for (int i = 0; i < phoneNumber.length(); i++) {char c = phoneNumber.charAt(i);if (!(c >= '0' && c <= '9')) {return false;}}//当循环结束之后,表示每一个字符都在0-9之间return true;}private static boolean checkPersonID(String personID) { //长度为18位if (personID.length() != 18) {return false;} //不能以0为开头if (personID.startsWith("0")) {//如果以0开头,那么返回falsereturn false;} //前17位,必须都是数字for (int i = 0; i < personID.length() - 1; i++) {char c = personID.charAt(i);//如果有一个字符不在0-9之间,那么直接返回falseif (!(c >= '0' && c <= '9')) {return false;}} //最为一位可以是数字,也可以是大写X或小写xchar endChar = personID.charAt(personID.length() - 1);if ((endChar >= '0' && endChar <= '9') || (endChar == 'x') || (endChar == 'X')) {return true;} else {return false;}}private static boolean contains(ArrayList<User> list, String username) { //循环遍历集合得到每一个用户对象 //拿着用户对象中的用户名进行比较for (int i = 0; i < list.size(); i++) {//i 索引User user = list.get(i);String rightUsername = user.getUsername();if(rightUsername.equals(username)){return true;}} //当循环结束了,表示集合里面所有的用户都比较完毕了,还没有一样的,则返回falsereturn false;}private static boolean checkUsername(String username) { //用户名长度必须在3~15位之间int len = username.length();if (len < 3 || len > 15) {return false;} //当代码执行到这里,表示用户名的长度是符合要求的。 //继续校验:只能是字母加数字的组合 //循环得到username里面的每一个字符,如果有一个字符不是字母或者数字,那么就返回falsefor (int i = 0; i < username.length(); i++) {//i 索引char c = username.charAt(i);if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))) {return false;}} //当代码执行到这里,表示什么? //用户名满足两个要求:1长度满足 2内容也满足(字母+数字) //但是不能是纯数字 //统计在用户名中,有多少字母就可以了。int count = 0;for (int i = 0; i < username.length(); i++) {//i 索引char c = username.charAt(i);if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {count++;break;}}return count > 0;}private static String getCode(){//1.创建一个集合添加所有的大写和小写字母ArrayList<Character> list = new ArrayList<>();for (int i = 0; i < 26; i++) {list.add((char)('a' + i));list.add((char)('A' + i));}StringBuilder sb = new StringBuilder();//2.要随机抽取4个字符Random r = new Random();for (int i = 0; i < 4; i++) {//获取随机索引int index = r.nextInt(list.size());//利用随机索引获取字符char c = list.get(index);//把随机字符添加到sb当中sb.append(c);}//3.把一个随机数字添加到末尾int number = r.nextInt(10);sb.append(number);//4.如果我们要修改字符串中的内容//先把字符串变成字符数组,在数组中修改,然后再创建一个新的字符串char[] arr = sb.toString().toCharArray();//拿着最后一个索引,跟随机索引进行交换int randomIndex = r.nextInt(arr.length);//最大索引指向的元素 跟随机索引指向的元素交换char temp = arr[randomIndex];arr[randomIndex] = arr[arr.length - 1];arr[arr.length - 1] = temp;return new String(arr);} }