ArrayList覆盖与空值异常:电影演员列表显示问题求助
解决电影演员列表覆盖及后续列表为空的问题
咱们一步步拆解你遇到的两个问题,然后给出不用Map的修复方案:
第一个问题:演员被覆盖的根源
最初的代码里,每次读取一行演员数据时,你都新建了一个ArrayList<Actor>,然后通过mudarActores直接替换掉电影的整个演员列表。这就导致之前添加的演员被彻底覆盖,最后只能看到最后一个读取的演员。
正确思路是:不要替换整个列表,而是往电影已有的演员列表里追加新演员。
修复第一步:给Filme类新增添加演员的方法
修改Filme类,新增一个专门用来添加演员的方法,避免直接替换列表:
public class Filme { // 保留你原有的属性和构造函数 public void adicionarActor(Actor actor) { this.actores.add(actor); } }
这个方法会直接操作电影已有的actores列表,不会覆盖之前的内容。
第二个问题:后续电影演员列表为null的原因
你修改后的代码里,Scanner在第一次外层循环时就读完了整个演员文件,当外层循环进入第二次时,leitorFicheiroA.hasNextLine()已经返回false,内层循环根本不会执行,也没有给后续电影设置演员列表。如果你的Filme对象初始化时actores是null,自然就会输出null。
这里有两种简单的修复方式:
方式一:每次处理电影时重新读取文件(适合小文件)
每次遍历一个电影ID时,都重新打开演员文件读取,筛选当前电影的演员。这种方式实现简单,不用额外缓存数据:
try{ String ficheiroActores = "Actorsfile.txt"; // 替换成你的实际文件名 int i = 0; // 注意:改成i < ids.length,原代码的length-1会漏掉最后一个电影 while (i < ids.length) { int idFilme = ids[i]; Filme filmeAtual = filmes.get(i); // 每次处理一个电影,重新打开文件和Scanner File ficheiroA = new File(ficheiroActores); Scanner leitorFicheiroA = new Scanner(ficheiroA); while (leitorFicheiroA.hasNextLine()) { String linha = leitorFicheiroA.nextLine(); String dadosA[] = linha.split(","); if (dadosA.length == 4) { int idFilmeA = Integer.parseInt(dadosA[3]); if (idFilmeA == idFilme) { Actor actor = new Actor(dadosA[1]); filmeAtual.adicionarActor(actor); // 用新增的添加方法 } } } leitorFicheiroA.close(); // 记得关闭Scanner,避免资源泄漏 i++; } } catch(FileNotFoundException e) { String mensagem = "Erro: o ficheiro " + ficheiroActores + " nao foi encontrado."; System.out.println(mensagem); }
方式二:先缓存所有演员数据(适合大文件)
先一次性把所有演员数据读取到一个临时列表里,然后遍历电影时从缓存里筛选对应ID的演员,这种方式效率更高,不用反复打开文件:
// 定义一个简单的辅助类,存储演员姓名和对应的电影ID class ActorFilme { String nomeActor; int idFilme; public ActorFilme(String nome, int id) { this.nomeActor = nome; this.idFilme = id; } } try{ String ficheiroActores = "Actorsfile.txt"; File ficheiroA = new File(ficheiroActores); Scanner leitorFicheiroA = new Scanner(ficheiroA); ArrayList<ActorFilme> todosActores = new ArrayList<>(); // 第一步:把所有演员数据读取到缓存列表 while (leitorFicheiroA.hasNextLine()) { String linha = leitorFicheiroA.nextLine(); String dadosA[] = linha.split(","); if (dadosA.length == 4) { int idFilmeA = Integer.parseInt(dadosA[3]); todosActores.add(new ActorFilme(dadosA[1], idFilmeA)); } } leitorFicheiroA.close(); // 第二步:遍历每个电影,从缓存里筛选对应演员 int i = 0; while (i < ids.length) { int idFilme = ids[i]; Filme filmeAtual = filmes.get(i); for(ActorFilme af : todosActores) { if (af.idFilme == idFilme) { Actor actor = new Actor(af.nomeActor); filmeAtual.adicionarActor(actor); } } i++; } } catch(FileNotFoundException e) { String mensagem = "Erro: o ficheiro " + ficheiroActores + " nao foi encontrado."; System.out.println(mensagem); }
额外小优化:避免Filme的actores为null
看你的Filme类构造函数,如果你初始化时传入的actores是null,会覆盖类里默认的空列表。修改构造函数,确保actores始终是有效的空列表:
public Filme(int id, String titulo, ArrayList<Actor> actores, ArrayList<GeneroCinematografico> generos,String ano,String mes,String dia) { this.id = id; this.titulo = titulo; // 如果传入的actores是null,就新建一个空列表 this.actores = (actores != null) ? actores : new ArrayList<>(); this.generos = (generos != null) ? generos : new ArrayList<>(); this.ano = ano; this.mes = mes; this.dia = dia; }
这样修改后,所有电影的演员列表都会正确显示,既不会被覆盖,也不会出现null的情况。
内容的提问来源于stack exchange,提问作者Afacs
相关产品推荐
相关产品推荐

