1

I'm having a problem where I read a textfile named "songs.txt" with Scanner in a function called loadFiles() which every line is:

Music ID @ Song Name @ Release Date

And with this I create a Song object, and then store said object in a ArrayList. After reading the file, I clone this ArrayList so I can return a ArrayList with the songs read and clear the first ArrayList to prevent the cases where for exemple:

(PS: I use the ArrayLists as global variables)

songs.txt has this structure:

1oYYd2gnWZYrt89EBXdFiO@Message In A Bottle@1979
7zxc7dmd82nd92nskDInds@Sweet Child of Mine@1980

And the loadFiles() is called 2 times, the ArrayList would have a size of 4 instead of 2 as it should be. So that's why after songs.txt is read I copy the arrayList and then clear the first ArrayList that way the ArrayList that's returned only has the size of 2.

This is my code:

package pt.ulusofona.aed.deisiRockstar2021;
import java.io.IOException;
import java.util.Scanner;
import java.io.*;
import java.util.ArrayList;

public class Main {
  public static ArrayList < Song > teste6 = new ArrayList < > ();
  public static ArrayList < Song > getSongsArray = new ArrayList < > ();
  public static ArrayList < Artista > testeSongArtists = new ArrayList < > ();
  public static ParseInfo parseInfoSongsTxT = new ParseInfo(0, 0);
  public static ParseInfo parseInfoSongsArtistsTxT = new ParseInfo(0, 0);
  public static ParseInfo parseInfoSongsDetailsTxT = new ParseInfo(0, 0);
  
  public static void main(String[] args) throws IOException {
    ArrayList < Song > teste7 = new ArrayList < Song > ();
    loadFiles();
    loadFiles();
    teste7 = getSongs();
    ParseInfo teste8 = getParseInfo("songs.txt");
    System.out.println("\n----------------------TESTE DO MAIN----------------------");
    System.out.println(teste7.toString());
    System.out.println(teste8.toString());
    System.out.println(getSongsArray.size());
  }
  
  public static void loadFiles() throws IOException {
    //Aqui lê-se o ficheiro songs.txt
    System.out.println("----------------------LEITURA DO FICHEIRO songs.txt------------");
    String nomeFicheiro = "songs.txt";
    try {
      File ficheiro = new File(nomeFicheiro);
      FileInputStream fis = new FileInputStream(ficheiro);
      Scanner leitorFicheiro = new Scanner(fis);
      while (leitorFicheiro.hasNextLine()) {
        String linha = leitorFicheiro.nextLine();
        String dados[] = linha.split("@");
        if (dados.length != 3) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[0].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[1].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[2].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        //Meter para ignorar a acabar com espaço
        parseInfoSongsTxT.NUM_LINHAS_OK += 1;
        String idTemaMusical = dados[0];
        String nome = dados[1];
        int anoLancamento = Integer.parseInt(dados[2]);
        Song song = new Song(idTemaMusical, nome, null, anoLancamento, 0, false, 0, 0, 0, 0);
        teste6.add(song);
      }
      leitorFicheiro.close();
      getSongsArray = (ArrayList < Song > ) teste6.clone();
      teste6.clear();
    } catch (FileNotFoundException exception) {
      String mensagem = "Erro: o ficheiro " + nomeFicheiro + " nao foi encontrado.";
      System.out.println(mensagem);
    }
    System.out.println(teste6.toString());
    System.out.println("Ok: " + parseInfoSongsTxT.NUM_LINHAS_OK + ", Ignored: " + parseInfoSongsTxT.NUM_LINHAS_IGNORED + "\n");
    System.out.println("----------------------LEITURA DO FICHEIRO song_artists.txt------------");
    //Aqui é lido o ficheiro song_artists.txt, mas falta ver se é preciso separar vários artistas com o mesmo ID para posições diferentes no ArrayList
    String nomeFicheiro2 = "song_artists.txt";
    try {
      File song_artists = new File(nomeFicheiro2);
      FileInputStream fis2 = new FileInputStream(song_artists);
      Scanner leitorFicheiro2 = new Scanner(fis2);
      while (leitorFicheiro2.hasNextLine()) {
        String linha = leitorFicheiro2.nextLine();
        String dados[] = linha.split("@");
        if (dados.length != 2) {
          parseInfoSongsArtistsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[0].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[1].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        parseInfoSongsArtistsTxT.NUM_LINHAS_OK += 1;
        String idTemaMusical = dados[0];
        String artista = dados[1];
        Artista artista2 = new Artista(idTemaMusical, artista);
        testeSongArtists.add(artista2);
      }
      leitorFicheiro2.close();
    } catch (FileNotFoundException exception) {
      String mensagem = "Erro: o ficheiro " + nomeFicheiro2 + " não foi encontrado.";
      System.out.println(mensagem);
    }
    System.out.println(testeSongArtists.toString());
    System.out.println("Ok: " + parseInfoSongsArtistsTxT.NUM_LINHAS_OK + ", Ignored: " + parseInfoSongsArtistsTxT.NUM_LINHAS_IGNORED + "\n");
    System.out.println("----------------------LEITURA DO FICHEIRO song_details.txt------------");
    //Aqui lê-se o ficheiro song_details.txt
    boolean letra = false;
    ArrayList < Song > testeSongDetails = new ArrayList < Song > ();
    String nomeFicheiro3 = "song_details.txt";
    try {
      File song_details = new File(nomeFicheiro3);
      FileInputStream fis3 = new FileInputStream(song_details);
      Scanner leitorFicheiro3 = new Scanner(fis3);
      while (leitorFicheiro3.hasNextLine()) {
        String linha = leitorFicheiro3.nextLine();
        String dados[] = linha.split("@");
        if (dados.length != 7) {
          parseInfoSongsDetailsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[0].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[1].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[3].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[4].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[5].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        if (Character.isWhitespace(dados[6].charAt(0))) {
          parseInfoSongsTxT.NUM_LINHAS_IGNORED += 1;
          continue;
        }
        parseInfoSongsDetailsTxT.NUM_LINHAS_OK += 1;
        String idTemaMusical = dados[0];
        //System.out.println(idTemaMusical);
        int duracao = Integer.parseInt(dados[1]);
        //System.out.println(duracao);
        int letraExplicita = Integer.parseInt(dados[2]);
        //System.out.println(letraExplicita);
        if (letraExplicita == 0) {
          letra = false;
        } else {
          letra = true;
        }
        //System.out.println(letra);
        int populariedade = Integer.parseInt(dados[3]);
        //System.out.println(populariedade);
        double dancabilidade = Double.parseDouble(dados[4]);
        //System.out.println(dancabilidade);
        double vivacidade = Double.parseDouble(dados[5]);
        //System.out.println(vivacidade);
        double volumeMedio = Double.parseDouble(dados[6]);
        //System.out.println(volumeMedio);
        Song song = new Song(idTemaMusical, null, null, 0, duracao, letra, populariedade, dancabilidade, vivacidade, volumeMedio);
        testeSongDetails.add(song);
      }
      leitorFicheiro3.close();
    } catch (FileNotFoundException exception) {
      String mensagem = "Erro: o ficheiro " + nomeFicheiro3 + " não foi encontrado.";
      System.out.println(mensagem);
    }
    System.out.println("Ok: " + parseInfoSongsDetailsTxT.NUM_LINHAS_OK + ", Ignored: " + parseInfoSongsDetailsTxT.NUM_LINHAS_IGNORED);
  }

  public static ArrayList < Song > getSongs() {
    return getSongsArray;
  }

  public static ParseInfo getParseInfo(String fileName) {
    if (fileName == "songs.txt") {
      return parseInfoSongsTxT;
    }
    if (fileName == "song_artists.txt") {
      return parseInfoSongsArtistsTxT;
    }
    if (fileName == "song_details.txt") {
      return parseInfoSongsDetailsTxT;
    }
    return null;
  }
}

The problem is that when I made a test to check the function where the ArrayList is returned to see the size of the ArrayList it always comes as 0.

I think it's because only the function the returns the ArrayList is tested so loadFiles() isn't executed so the ArrayListo never gets cloned and that makes the ArrayList that is returned stay the same.

I thought about calling loadFiles() inside getSongs() and that way I would guarantee that the ArrayList is cloned but that would make getSongs use "throws IOException" and since I have to respect the school's project guide and getSongs doesn't include "throws IOException" i can't put it there.

But the more I think about it, that doesn't even make sense because how can they test it with a file of their own and loadFiles() isn't executed?

I'm out of ideas how to solve this problem, any help is welcome thank you.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Welcome to Stack Overflow! Do you want to include the code where you're calling all of this? – Henry Twist Apr 10 '21 at 23:22
  • Added all of the code. – Telmo Alexandre Apr 10 '21 at 23:45
  • 1
    [Click on the link to find out why not to do this -> if (fileName == "songs.txt")](https://stackoverflow.com/q/513832/2587435) – Paul Samsotha Apr 11 '21 at 00:31
  • 1
    As an aside, instead of making one large method (loadFiles()), you should split up your code into a few methods that do one thing each and call those methods in the loadFiles() method. Having those smaller methods will allow you to test just those methods by themselves to make sure all the logic is sound and everything works as expected. Also, it really helps with readability. – Paul Samsotha Apr 11 '21 at 00:37
  • @PaulSamsotha that's actually very usefull, I just thought that since they said I had to use loadFiles() to read the files I thought everything had to be done inside loadFiles(). I just hope that if I use other fuctions to read each file, and then call them inside loadFiles() it counts as loadFiles() reading the files. Thank you ! Also already changed the " fileName == "songs.txt" " to the method you linked! – Telmo Alexandre Apr 11 '21 at 00:40

0 Answers0