基本数据类型
数据值是存储在自己的空间中。
特点:赋值给其他变量,也是赋的真实的值。
引用数据类型
数据值是存储在其他空间中,自己空间中存储的是地址值。
特点:赋值给其他变量,赋的地址值。
综合练习
使用 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~9 result += 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.(总和 - 最大值 - 最小值 )/4 int 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~100 Scanner 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.加密 //每位数加上5 for (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.每一位减5 for (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.遍历newArr for (int i = 0; i < newArr.length; i++) { System.out.println(newArr[i]); } } //判断prize在数组当中是否存在 //存在:true //不存在:false public 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个蓝球 数组长度: 7 int[] 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~16 while (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个蓝球 数组长度: 7 int[] 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 + insert alt + 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 ~ 20 int hurt = r.nextInt(20) + 1; //剩余血量 int remainBlood = role.getBlood() - hurt; //对剩余血量做一个验证,如果为负数了,就修改为0 remainBlood = 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开始攻击r2 r1.attack(r2); //判断r2的剩余血量 if(r2.getBlood() == 0){ System.out.println(r1.getName() + " K.O了" + r2.getName()); break; } //r2开始攻击r1 r2.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 123 System.out.println(num1);//123 System.out.println("请输入第二个整数"); int num2 = sc.nextInt();//不会让你输入 直接接收内存中剩余的123 System.out.println(num2);//123
Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串"); String line1 = sc.nextLine();//输入123 bcd System.out.println(line1);//输出123 bcd System.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){ //获取数组中学生对象的id int 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,否则为 false boolean 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 2 System.out.println("请输入用户名"); String username = sc.next(); System.out.println("请输入密码"); String password = sc.next(); //3.比较 if (username.equals(rightUsername) && password.equals(rightPassword)) { System.out.println("用户登录成功"); break; } else { if(i == 2){ //最后一次机会也输入错误,此时要提示账号被锁定 System.out.println("账号" + username + "被锁定,请联系黑马程序员官方客服小姐姐: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,输出结果 cba String 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' ---> 57 int 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());//34 System.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:长度为小于等于9 if (str.length() > 9) { return false; } //要求2:只能是数字 for (int i = 0; i < str.length(); i++) { char c = str.charAt(i);//0~9 if (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; } } //所有的情况都比较完毕了,还不一样那么直接返回false return 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 Byte short Short char Character int Integer long Long float Float double Double boolean 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); } } //返回resultList return resultList; } }
学生管理系统
import java.util.ArrayList; import java.util.Scanner; public class StudentSystem { public static void main(String[] args) { ArrayList<Student> list = new ArrayList<>(); // 给循环起名为loop loop: 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); //得到每一个学生对象的id String 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开头,那么返回false return false; } //前17位,必须都是数字 for (int i = 0; i < personID.length() - 1; i++) { char c = personID.charAt(i); //如果有一个字符不在0-9之间,那么直接返回false if (!(c >= '0' && c <= '9')) { return false; } } //最为一位可以是数字,也可以是大写X或小写x char 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; } } //当循环结束了,表示集合里面所有的用户都比较完毕了,还没有一样的,则返回false return false; } private static boolean checkUsername(String username) { //用户名长度必须在3~15位之间 int len = username.length(); if (len < 3 || len > 15) { return false; } //当代码执行到这里,表示用户名的长度是符合要求的。 //继续校验:只能是字母加数字的组合 //循环得到username里面的每一个字符,如果有一个字符不是字母或者数字,那么就返回false for (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); } }