
在处理文件输入时,开发者经常会遇到两种主要问题:
在给定的电影信息处理案例中,原始代码在尝试解析电影年份和流派时遇到了上述问题。例如,当文件中的一行数据为 Schindler's List, 1994, War, R 时:
这些问题的根源在于文件数据中的额外空格,而默认的 String.split(",") 方法无法自动处理这些空格。
为了解决上述问题,我们需要在数据读取和解析阶段进行必要的清洗。有两种主要方法可以实现这一点:
String.trim() 方法可以移除字符串两端的空白字符(包括空格、制表符、换行符等)。这是最直接且易于理解的方法。在解析每个字段后,立即调用 trim() 方法。
立即学习“Java免费学习笔记(深入)”;
// 原始代码:
// String[] movieInfo = movie.split(",");
// String title = movieInfo[0];
// int year = Integer.parseInt(movieInfo[1]);
// String genre = movieInfo[2];
// 改进后:
String[] movieInfo = movie.split(",");
String title = movieInfo[0].trim(); // 移除标题两端空格
int year = Integer.parseInt(movieInfo[1].trim()); // 移除年份两端空格后再转换
String genre = movieInfo[2].trim(); // 移除流派两端空格
String rating = movieInfo[3].trim(); // 移除评分两端空格通过在每个字段上调用 trim(),可以确保 Integer.parseInt() 接收到纯数字字符串,并且流派字符串与预定义的常量完全匹配。
更优雅且推荐的方法是利用正则表达式来增强 split() 方法。我们可以让 split() 不仅在逗号处分割,还能自动忽略逗号后的任意数量的空白字符。
// 改进后:
// 使用正则表达式 ",\s*"。
// "," 表示匹配一个逗号。
// "\s*" 表示匹配零个或多个空白字符(空格、制表符、换行符等)。
String[] movieInfo = movie.split(",\s*");
String title = movieInfo[0]; // 无需再trim,因为split已经处理了
int year = Integer.parseInt(movieInfo[1]); // 无需再trim
String genre = movieInfo[2]; // 无需再trim
String rating = movieInfo[3]; // 无需再trim这种方法简化了后续代码,因为每个 movieInfo 数组元素在被访问时已经去除了前导空白。
为了实现按年份对电影进行排序,我们需要定义一个 Comparator。Comparator 是一个函数式接口,用于定义两个对象之间的比较规则。
import java.util.Comparator;
public class MovieComparator implements Comparator<Movie> {
@Override
public int compare(Movie m1, Movie m2) {
// 按照年份升序排序
return Integer.compare(m1.getYearReleased(), m2.getYearReleased());
}
}有了 MovieComparator,就可以使用 ArrayList 的 sort() 方法对电影列表进行排序:
adventure.sort(new MovieComparator()); drama.sort(new MovieComparator()); // ... 对其他所有流派列表进行排序
以下是整合了数据清洗和排序功能的完整 Java 代码示例。
假设 MovieListing.txt 文件内容如下(请注意逗号后的空格):
Steven Spielberg John Williams Schindler's List, 1994, War, R Amistad, 1997, Drama, R The Post, 2017, Drama, PG-13 E.T. the Extra-Terrestrial, 1982, Sci Fi, PG Jurassic Park, 1993, Sci Fi, PG-13
public class Director {
private String directorName;
private String composerName;
public Director(String d, String c) {
this.directorName = d;
this.composerName = c;
}
public String getDirectorName() {
return directorName;
}
public void setDirectorName(String directorName) {
this.directorName = directorName;
}
public String getComposerName() {
return composerName;
}
public void setComposerName(String composerName) {
this.composerName = composerName;
}
}public class Movie extends Director { // 注意:Movie继承Director在面向对象设计上可能不合理,但此处保留原结构
private String title;
private int yearReleased;
private String genre;
private String rating;
public Movie(String title, int yearReleased, String genre, String rating, String directorName, String composerName) {
super(directorName, composerName);
this.title = title;
this.yearReleased = yearReleased;
this.genre = genre;
this.rating = rating;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getYearReleased() {
return yearReleased;
}
public void setYearReleased(int yearReleased) {
this.yearReleased = yearReleased;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
@Override
public String toString() { // 重写toString方便调试输出
return "Movie{" +
"title='" + title + ''' +
", yearReleased=" + yearReleased +
", genre='" + genre + ''' +
", rating='" + rating + ''' +
", director='" + getDirectorName() + ''' +
", composer='" + getComposerName() + ''' +
'}';
}
}import java.util.Comparator;
public class MovieComparator implements Comparator<Movie> {
@Override
public int compare(Movie m1, Movie m2) {
// 按照年份升序排序
return Integer.compare(m1.getYearReleased(), m2.getYearReleased());
}
}import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;
import java.io.*;
public class Driver {
public void start() throws FileNotFoundException {
// Initialize arraylists
ArrayList<Movie> adventure = new ArrayList<>();
ArrayList<Movie> drama = new ArrayList<>();
ArrayList<Movie> fantasy = new ArrayList<>();
ArrayList<Movie> romance = new ArrayList<>();
ArrayList<Movie> sciFi = new ArrayList<>();
ArrayList<Movie> thriller = new ArrayList<>();
ArrayList<Movie> war = new ArrayList<>();
String directorName = "";
String composerName = "";
File myObj = new File("MovieListing.txt");
try (Scanner myReader = new Scanner(myObj)) { // 使用try-with-resources确保Scanner关闭
if (myReader.hasNextLine()) {
directorName = myReader.nextLine().trim(); // 读取并trim导演名
}
if (myReader.hasNextLine()) {
composerName = myReader.nextLine().trim(); // 读取并trim作曲家名
}
while (myReader.hasNextLine()) {
String movieLine = myReader.nextLine();
// 改进点:使用正则表达式 ",\s*" 分割字符串,自动处理逗号后的空格
String[] movieInfo = movieLine.split(",\s*");
if (movieInfo.length < 4) { // 简单的数据完整性检查
System.err.println("Skipping malformed line: " + movieLine);
continue;
}
String title = movieInfo[0];
int year = Integer.parseInt(movieInfo[1]);
String genre = movieInfo[2];
String rating = movieInfo[3];
Movie movie1 = new Movie(title, year, genre, rating, directorName, composerName);
// sort movies into arraylists
if (genre.equals("Adventure")) {
adventure.add(movie1);
} else if (genre.equals("Drama")) {
drama.add(movie1);
} else if (genre.equals("Fantasy")) {
fantasy.add(movie1);
} else if (genre.equals("Romance")) {
romance.add(movie1);
} else if (genre.equals("Sci Fi")) {
sciFi.add(movie1);
} else if (genre.equals("Thriller")) {
thriller.add(movie1);
} else if (genre.equals("War")) {
war.add(movie1);
}
}
} catch (FileNotFoundException e) {
System.err.println("Error: MovieListing.txt not found. " + e.getMessage());
throw e; // 重新抛出异常,让调用者处理
} catch (NumberFormatException e) {
System.err.println("Error parsing number: " + e.getMessage());
// 可以选择跳过该行或进行其他错误处理
}
// 调试输出,检查列表是否已填充
System.out.println("Adventure Movies: " + adventure);
System.out.println("War Movies: " + war); // 示例
// Ask the user which genre they would like to view
String genreChoice = JOptionPane.showInputDialog("Director: " + directorName + "
" +
"Composer: " + composerName + "
" +
"Which genre would you like?
" +
"1. Adventure
" +
"2. Drama
" +
"3. Fantasy
" +
"4. Romance
" +
"5. SciFi
" +
"6. Thriller
" +
"7. War
" +
"Your choice: ");
// Sort all movie lists by year released
MovieComparator movieComparator = new MovieComparator();
adventure.sort(movieComparator);
drama.sort(movieComparator);
fantasy.sort(movieComparator);
romance.sort(movieComparator);
sciFi.sort(movieComparator);
thriller.sort(movieComparator);
war.sort(movieComparator);
// Display the output dialog box
StringBuilder output = new StringBuilder();
output.append("Director: ").append(directorName).append("
");
output.append("Composer: ").append(composerName).append("
");
output.append("Genre: ");
ArrayList<Movie> selectedGenreList = null;
String genreName = "";
switch (genreChoice) {
case "1":
selectedGenreList = adventure;
genreName = "Adventure";
break;
case "2":
selectedGenreList = drama;
genreName = "Drama";
break;
case "3":
selectedGenreList = fantasy;
genreName = "Fantasy";
break;
case "4":
selectedGenreList = romance;
genreName = "Romance";
break;
case "5":
selectedGenreList = sciFi;
genreName = "Sci Fi";
break;
case "6":
selectedGenreList = thriller;
genreName = "Thriller";
break;
case "7":
selectedGenreList = war;
genreName = "War";
break;
default:
JOptionPane.showMessageDialog(null, "Invalid genre choice.");
return;
}
output.append(genreName).append("
");
output.append("Movie Title Year Released Rating
");
if (selectedGenreList != null) {
for (Movie movie : selectedGenreList) {
output.append(String.format("%-20s %-15d %s
",
movie.getTitle(),
movie.getYearReleased(),
movie.getRating()));
}
}
JOptionPane.showMessageDialog(null, output.toString());
}
}import java.io.FileNotFoundException;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
Driver driver = new Driver();
driver.start();
}
}通过上述改进,我们不仅解决了 ArrayList 为空和 NumberFormatException 的问题,还使文件数据处理流程更加健壮和专业。这对于任何需要处理外部数据的 Java 应用来说都是基本且重要的实践。
以上就是Java 文件解析与数据处理:解决 ArrayList 空值及排序问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号