如何通过Scanner与substring实现电影收藏的编辑功能?
解决电影收藏编辑功能的字符串提取与属性修改问题
我明白你现在的困境——你想从ArrayList转换后的字符串里定位到用户输入的影片,提取它的完整信息后进行属性编辑,但目前的substring用法确实有误(contains()返回布尔值,不能直接作为索引参数)。咱们一步步来修复这个问题:
一、正确提取目标影片的完整信息
首先,你需要先定位到用户输入影片名在字符串中的位置,再找到该影片条目完整的起止索引,才能准确截取内容。假设你的editArrayString是多个影片条目拼接而成(每个条目以Film Name:-开头),可以这样修改第一个循环:
Scanner editScanner = new Scanner(System.in); boolean editInterface = true; String chosenFilm = null; while (editInterface) { System.out.println("请输入要编辑的影片名:"); String editScannerInput = editScanner.nextLine().trim(); // 找到用户输入影片名在字符串中的起始位置(忽略大小写) int nameStartIndex = editArrayString.toLowerCase().indexOf(editScannerInput.toLowerCase()); if (nameStartIndex == -1) { System.out.println("你的收藏中没有该影片,请输入收藏内存在的影片名。"); continue; } // 定位到当前影片条目的真正起始点(回到"Film Name:-"的开头) int filmStartIndex = editArrayString.lastIndexOf("Film Name:-", nameStartIndex); if (filmStartIndex == -1) filmStartIndex = nameStartIndex; // 极端兼容处理 // 找到下一个影片条目的起始位置,作为当前影片的结束点 int nextFilmStart = editArrayString.indexOf("Film Name:-", filmStartIndex + 1); int filmEndIndex = (nextFilmStart == -1) ? editArrayString.length() : nextFilmStart; // 截取完整的影片信息 chosenFilm = editArrayString.substring(filmStartIndex, filmEndIndex).trim(); System.out.println("找到目标影片:\n" + chosenFilm); editInterface = false; }
二、优化属性编辑逻辑
你当前的第二个循环存在问题:没有重新获取用户要编辑的属性名称,而是直接复用了之前的影片名输入。这里不仅要修正输入逻辑,还要增加输入合法性验证,同时建议直接操作Film对象而非字符串(更高效不易出错):
方案1:基于字符串解析的编辑(如果必须用字符串)
boolean editInterfaceAttribute = true; // 先解析已提取的影片字符串,获取当前属性值 String[] attrParts = chosenFilm.split(", "); String currentName = attrParts[0].replace("Film Name:- ", ""); int currentDuration = Integer.parseInt(attrParts[1].replace("Film Duration (in mins):- ", "")); int currentYear = Integer.parseInt(attrParts[2].replace("Film Release Year:- ", "")); int currentRating = Integer.parseInt(attrParts[3].replace("Rating Out of 5:- ", "")); while (editInterfaceAttribute) { System.out.println("你想编辑哪个属性?(Name/Duration/Year/Rating)"); String attrInput = editScanner.nextLine().trim().toLowerCase(); switch (attrInput) { case "name": System.out.println("请输入新的影片名:"); String newName = editScanner.nextLine().trim(); // 这里可以更新字符串或ArrayList中的对应条目 System.out.println("影片名已更新为:" + newName); editInterfaceAttribute = false; break; case "duration": System.out.println("请输入新的时长(分钟):"); while (!editScanner.hasNextInt()) { System.out.println("请输入有效数字:"); editScanner.next(); } int newDuration = editScanner.nextInt(); editScanner.nextLine(); // 清除输入缓冲区的换行符 System.out.println("影片时长已更新为:" + newDuration + "分钟"); editInterfaceAttribute = false; break; case "year": System.out.println("请输入新的上映年份:"); while (!editScanner.hasNextInt()) { System.out.println("请输入有效数字:"); editScanner.next(); } int newYear = editScanner.nextInt(); editScanner.nextLine(); System.out.println("上映年份已更新为:" + newYear); editInterfaceAttribute = false; break; case "rating": System.out.println("请输入新的评分(1-5):"); int newRating = 0; do { while (!editScanner.hasNextInt()) { System.out.println("请输入1-5之间的有效数字:"); editScanner.next(); } newRating = editScanner.nextInt(); } while (newRating < 1 || newRating > 5); editScanner.nextLine(); System.out.println("影片评分已更新为:" + newRating + "/5"); editInterfaceAttribute = false; break; default: System.out.println("输入的属性无效,请输入Name、Duration、Year或Rating。"); } }
方案2:直接操作ArrayList中的Film对象(更推荐)
相比操作字符串,直接遍历ArrayList找到对应的Film实例并修改属性,代码更简洁且不易出错:
// 假设你的影片集合是ArrayList<Film> filmList; Film targetFilm = null; boolean editInterface = true; while (editInterface) { System.out.println("请输入要编辑的影片名:"); String editScannerInput = editScanner.nextLine().trim(); // 遍历集合找到匹配的影片 for (Film film : filmList) { if (film.getFilmName().toLowerCase().contains(editScannerInput.toLowerCase())) { targetFilm = film; break; } } if (targetFilm == null) { System.out.println("你的收藏中没有该影片,请重新输入。"); } else { System.out.println("找到目标影片:\n" + targetFilm.toString()); editInterface = false; } } // 编辑属性 boolean editInterfaceAttribute = true; while (editInterfaceAttribute) { System.out.println("你想编辑哪个属性?(Name/Duration/Year/Rating)"); String attrInput = editScanner.nextLine().trim().toLowerCase(); switch (attrInput) { case "name": System.out.println("请输入新的影片名:"); targetFilm.setFilmName(editScanner.nextLine().trim()); System.out.println("影片名更新成功!"); editInterfaceAttribute = false; break; case "duration": System.out.println("请输入新的时长(分钟):"); while (!editScanner.hasNextInt()) { System.out.println("请输入有效数字:"); editScanner.next(); } targetFilm.setDurationInMins(editScanner.nextInt()); editScanner.nextLine(); System.out.println("时长更新成功!"); editInterfaceAttribute = false; break; // Year和Rating的修改逻辑类似,直接调用对应的set方法即可 default: System.out.println("输入的属性无效,请重新输入。"); } }
关键注意点
- 不要用布尔值作为substring参数:
contains()返回的是boolean,必须用indexOf()获取具体索引位置才能截取字符串。 - 优先操作对象而非字符串:直接修改ArrayList中的
Film实例,避免字符串解析带来的繁琐和错误风险。 - 输入合法性验证:对于数字类型的属性(时长、年份、评分),要确保用户输入的是有效数字,避免
NumberFormatException。
内容的提问来源于stack exchange,提问作者marrimred99
相关产品推荐
相关产品推荐

