Java进阶实战 | 4道经典案例从String玩转ArrayList

适合人群:掌握了Java基础语法,正在学习String API和ArrayList集合的同学

涉及知识点:String常用方法(equals、split、contains、charAt)、StringBuilder、Scanner交互、ArrayList增删改查、循环控制技巧、Java文本块

阅读时长:约15分钟


目录

  • 案例一:用户登录系统(3次机会)
  • 案例二:String实现随机验证码
  • 案例三:ArrayList批量删除技巧
  • 案例四:ArrayList书籍管理系统
  • 总结与知识体系

案例一:用户登录系统(3次机会)

问题描述

系统正确的登录名和密码是杳杉/666,请在控制台开发一个登录界面,接收用户输入的登录名和密码,判断用户是否登录成功。登录成功后展示"欢迎进入系统!",最多给用户三次登录机会。

解题思路

  1. for循环控制最多3次尝试
  2. 每次用Scanner.nextLine()接收一行输入,split(" ")拆分用户名和密码
  3. 将登录逻辑封装为login()方法,返回不同结果字符串
  4. 登录成功 → 打印欢迎语 +break退出
  5. 登录失败 → 提示剩余次数,3次用完直接结束

代码实现

package org.example; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i = 0; i < 3; i++) { // 1. 接收用户输入 System.out.println("请输入登录名和密码(以空格隔开):"); String temp = sc.nextLine(); String[] arr = temp.split(" "); String userName = arr[0]; String userPassWord = arr[1]; // 2. 登录逻辑 String result = login(userName, userPassWord); if ("success".equals(result)) { System.out.println("欢迎进入系统!"); break; } else { System.out.println(2 - i == 0 ? "登录失败!" : result + "!您还剩下" + (2 - i) + "次机会"); } } } public static String login(String loginName, String passWord) { // 定义正确账号和密码 String okLoginName = "杳杉"; String okPassWord = "666"; // 判断账号和密码 if (okLoginName.equals(loginName)) { if (okPassWord.equals(passWord)) { return "success"; } else { return "登录密码错误"; } } else { return "登录账号错误"; } } }

运行结果

请输入登录名和密码(以空格隔开): admin 111 登录账号错误!您还剩下2次机会 请输入登录名和密码(以空格隔开): 杳杉 000 登录密码错误!您还剩下1次机会 请输入登录名和密码(以空格隔开): 杳杉 123456 欢迎进入系统!

知识点小结

知识点代码体现说明
String.equals()okLoginName.equals(loginName)字符串内容比较,不能用==
String.split()temp.split(" ")按分隔符拆分字符串为数组
"常量".equals(变量)"success".equals(result)常量在前避免 NPE
for+break循环3次,成功则break限制次数的经典写法
剩余次数计算2 - ii从0开始,第1次剩余2次

案例二:String实现随机验证码

问题描述

使用 String 来开发验证码,实现随机产生验证码,验证码的每位可能是数字、大写字母、小写字母。

解题思路

  1. 准备一个包含所有可能字符的 String 字符池(大小写字母 + 数字)
  2. 循环 n 次,每次从字符池中随机取一个字符
  3. StringBuilder.append()拼接,效率高于String +=
  4. Random.nextInt(code.length())生成随机索引,charAt(ind)取字符

代码实现

package org.example; import java.util.Random; public class Main { public static void main(String[] args) { System.out.println("输出 5 位长度的验证码: " + randomCode(5)); System.out.println("输出 8 位长度的验证码: " + randomCode(8)); } public static StringBuilder randomCode(int n) { StringBuilder s = new StringBuilder(); Random r = new Random(); // 字符池:小写字母 + 大写字母 + 数字 String code = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; for (int i = 0; i < n; i++) { int ind = r.nextInt(code.length()); s.append(code.charAt(ind)); } return s; } }

运行结果

输出 5 位长度的验证码: K3m7Xa 输出 8 位长度的验证码: p2R9bN1c

知识点小结

知识点代码体现说明
String.charAt(i)code.charAt(ind)按索引取字符
Random.nextInt(n)r.nextInt(code.length())生成[0, n)随机数
StringBuilders.append(...)循环拼接首选,比+=高效
字符池思想String code = "abc...XYZ0-9"把可选字符集中管理,取用方便

对比:之前用switch+ ASCII 码生成验证码Java基础实战 | 7道经典编程题详解(if分支、switch、数组、加密算法一网打尽),需要3个分支分别处理数字、大写、小写。这次用字符池方式,一行charAt搞定,代码更简洁、可读性更好。两种方式各有优势,switch方式更灵活(可以控制各类字符的比例),字符池方式更简洁。


案例三:ArrayList批量删除技巧

问题描述

购物车中存储了如下商品:pythonpython课程实战JAVA人工智能Harness实战课程。现在用户想批量删除所有包含"python"的商品,请完成该需求。

解题思路

ArrayList 删除元素时有一个经典陷阱:删除后后面的元素会前移,导致索引变化。有两种正确做法:

方法一:正序遍历 + i–

  • 删除后让i回退一位,确保不漏掉紧挨着被删元素的下一个

方法二:倒序遍历(推荐)

  • 从后往前遍历,删除元素不影响前面未遍历的索引

代码实现

package org.example; import java.util.ArrayList; public class Main { public static void main(String[] args) { // 方法一:正序遍历 + i-- ArrayList<String> ali = new ArrayList<>(); ali.add("python"); ali.add("python课程实战"); ali.add("JAVA"); ali.add("人工智能"); ali.add("Harness实战课程"); for (int i = 0; i < ali.size(); i++) { String name = ali.get(i); if (name.contains("python")) { ali.remove(name); i--; // 删除后回退索引,确保不漏数据 } } System.out.println("方法一结果: " + ali); System.out.println("----------------------------------------------"); // 方法二:倒序遍历(推荐) ArrayList<String> ali1 = new ArrayList<>(); ali1.add("python"); ali1.add("python课程实战"); ali1.add("JAVA"); ali1.add("人工智能"); ali1.add("Harness实战课程"); for (int i = ali1.size() - 1; i >= 0; i--) { String name = ali1.get(i); if (name.contains("python")) { ali1.remove(name); } } System.out.println("方法二结果: " + ali1); } }

运行结果

方法一结果: [JAVA, 人工智能, Harness实战课程] ---------------------------------------------- 方法二结果: [JAVA, 人工智能, Harness实战课程]

知识点小结

知识点代码体现说明
ArrayList.add()ali.add("python")添加元素
ArrayList.get(i)ali.get(i)按索引取元素
ArrayList.remove()ali.remove(name)删除元素,后面的元素前移
String.contains()name.contains("python")判断是否包含子串
删除陷阱正序删除导致跳过删除后索引变化,相邻元素被跳过

核心要点:删除元素时,正序遍历必须i--,倒序遍历则天然安全。倒序遍历是首选,代码更简洁、不易出错。


案例四:ArrayList书籍管理系统

问题描述

完成书籍的上架、下架以及书籍信息浏览功能。用户通过菜单选择操作,系统响应执行。

解题思路

  1. ArrayList<Book>存储书籍,比数组更灵活(动态扩容)
  2. addBook()— 上架:录入信息 → 校验 → 添加
  3. delBook()— 下架:按ID查找 → 删除
  4. showBook()— 浏览:遍历输出
  5. start()— 菜单入口:用switch分发操作

代码实现

实体类:Book.java
package org.example; public class Book { private int id; private String name; private String author; private String createTime; public Book() {} public Book(int id, String name, String author, String createTime) { this.id = id; this.name = name; this.author = author; this.createTime = createTime; } 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 String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } @Override public String toString() { return id + "\t" + name + "\t" + author + "\t" + createTime; } }
业务类:BookOperator.java
package org.example; import java.util.ArrayList; import java.util.Scanner; public class BookOperator { private ArrayList<Book> books = new ArrayList<>(); private Scanner sc = new Scanner(System.in); // 上架书籍 private void addBook() { System.out.println("请依次填入 id 名称 作者 出版日期(以空格隔开)"); sc.skip("\\s*"); String temp = sc.nextLine(); // 1. 检查空输入 if (temp == null || temp.trim().isEmpty()) { System.out.println("输入不能为null或空!"); return; } // 2. 分割字符串 String[] s = temp.trim().split("\\s+"); // 3. 检查字段数量 if (s.length != 4) { System.out.println("格式错误!需要4个字段,您输入了 " + s.length + " 个"); return; } // 4. 转换ID int id; try { id = Integer.parseInt(s[0].trim()); } catch (NumberFormatException e) { System.out.println("ID必须是数字!您输入的是:" + s[0]); return; } // 5. 检查ID是否已存在 for (Book b : books) { if (b.getId() == id) { System.out.println("ID '" + id + "' 已存在!"); return; } } // 6. 创建并添加书籍 books.add(new Book(id, s[1], s[2], s[3])); System.out.println("上架成功!"); } // 下架书籍 private void delBook() { System.out.print("请输入要下架书籍的ID:"); int id = sc.nextInt(); for (int i = 0; i < books.size(); i++) { if (books.get(i).getId() == id) { books.remove(i); System.out.println("书籍下架成功!"); return; } } System.out.println("未找到ID为 " + id + " 的书籍"); } // 展示所有书籍 private void showBook() { System.out.println("<图书管理系统所有书籍>"); System.out.println("编号\t书名\t\t\t作者\t\t创作时间"); System.out.println("------------------------------------------------"); for (int i = 0; i < books.size(); i++) { System.out.println(books.get(i)); } } // 菜单入口 public void start() { // 预置一本初始书籍 books.add(new Book(1, "Python编程快速上手", "Al Sweigart", "2021-03-15")); System.out.print( """ ==========图书管理系统============ 1. 上架书籍 2. 下架书籍 3. 展示所有书籍 ================================ 请输入您的操作: """); System.out.print("> "); int n = sc.nextInt(); switch (n) { case 1 -> addBook(); case 2 -> delBook(); case 3 -> showBook(); default -> System.out.println("您的输入有误!"); } } }
测试类:Main.java
package org.example; public class Main { public static void main(String[] args) { BookOperator allBook = new BookOperator(); allBook.start(); } }

运行结果

==========图书管理系统============ 1. 上架书籍 2. 下架书籍 3. 展示所有书籍 ================================ 请输入您的操作: > 3 <图书管理系统所有书籍> 编号 书名 作者 创作时间 ------------------------------------------------ 1 Python编程快速上手 Al Sweigart 2021-03-15

知识点小结

知识点代码体现说明
ArrayList<Book>private ArrayList<Book> books泛型集合,类型安全
split("\\s+")temp.trim().split("\\s+")正则匹配多个空格
try-catchInteger.parseInt(...)异常处理校验数字格式
toString()重写books.get(i)直接打印Book重写后可直接输出
Java文本块"""菜单字符串Java 15+ 特性,多行字符串
switch箭头语法case 1 -> addBook()Java 14+ 增强,无需break

总结与知识体系

四道案例知识点对照表

案例核心知识点关键API/技巧
用户登录String比较 + 循环控制equals()、split()、for+break
验证码生成字符池 + StringBuildercharAt()、StringBuilder.append()
批量删除ArrayList删除陷阱contains()、remove()、倒序遍历
书籍管理ArrayList综合应用add/remove/get、泛型、文本块、异常处理

从String到ArrayList的进阶路线

String(不可变字符串) │ equals / split / contains / charAt │ ▼ StringBuilder(可变字符串) │ append / 高效拼接 │ ▼ ArrayList(动态数组集合) │ add / remove / get / size │ ▼ 综合应用(书籍管理系统) 实体类 + 业务类 + 菜单交互

编程思维总结

  1. 方法封装:登录逻辑封装为login(),验证码封装为randomCode(),单一职责
  2. 删除安全意识:ArrayList边遍历边删除必须注意索引变化,倒序遍历最安全
  3. 输入校验意识:书籍上架时校验空输入、字段数量、ID格式、ID重复
  4. 字符串处理三板斧split拆分、contains判断包含、equals比较

ArrayList vs 数组对比

对比维度数组Book[]ArrayListArrayList<Book>
长度固定,创建时指定动态扩容,自动增长
添加需手动管理索引add()一行搞定
删除需手动移动元素remove()自动调整
遍历for + lengthfor + size()或增强for
适用场景长度固定、性能优先长度可变、开发效率优先

如果觉得有帮助,欢迎点赞 + 收藏 + 关注!后续会持续分享Java集合框架、IO流、多线程等进阶内容~

有问题欢迎评论区交流!