TheGeek
TheGeek

Reputation: 23

How to use constructor to set other fields that are not inside constructor

I'm making a guess the movie game in which i take a list of movies from a text file. I have two classes for it Game for getting a random movie and Main for the rest of the game. Now i thought of adding a choice for hollywood or bollywood movies by changing the text files in Game. I take 'h' or 'b' respectively as inputs. I call the constructor of Game with parameters to choose file accordingly but it doesn't work and ALWAYS the file is null and showing NullPointerException.

This image showing what happens during debugging. It skips the setMovieList and constructor and comes to the next line

EDIT: I am new to OOPs so please bear with me. I just saw during debugging that the debugger first goes to the class fields and THEN to the constructor, I was actually trying to use file(which is inside the constructor) for the initialization of other fields because of which its value was null and was showing NullPointerException.

Now my question really remains how to use file and noOfMovies to initialize other fields in Game.

              //showing the setter method that i tried
//Main class
/*only showing the part having Game class*/

//making an object of Game class to get a random movie from the file
    System.out.println("Enter 'h' for hollywood and 'b' for bollywood ");
    Scanner input = new Scanner(System.in);
    char genre = input.next().charAt(0);
    Game newGame = new Game(genre);


//Game class
public class Game
{

    public Game(char genre)
    {
        setMovieList(genre);
    }
    File file;
    int noOfMovies;

    public void setMovieList(char genre)
    {
        if(genre == 'h')
        {
            this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\hollywoodMovies.txt");
            this.noOfMovies = 30;
        }
        else if(genre == 'b')
        {
            this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\bollywoodMovies.txt");
            this.noOfMovies = 20;
        }

    // EDIT ------> I want to initialize the below fields <-------

        private Scanner scan = new Scanner(this.file);

        private int lineCount = 0;
        int random = (int)(Math.random()*noOfMovies)+1;

        //array for storing the movie titles
        private String[] movieArray = new String[noOfMovies];


    }




Upvotes: 0

Views: 670

Answers (2)

D Gub
D Gub

Reputation: 26

I'm not sure.. maybe you want to get a result like this:

GAME CLASS

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Game {

    private File file = null;
    //private int noOfMovies = 0;
    private List<String> movies= null;
    FileInputStream read = null;

public Game(char genre) {
     movies = getMovieList();
     System.out.println(movies);
}

public void setMovieList(char genre) {
    if (genre == 'h') {
        this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\hollywoodMovies.txt");
      //  this.noOfMovies = 30;
    } else if (genre == 'b') {
        this.file = new File("C:\\Users\\Rashim\\Desktop\\java\\GuessTheMovie\\src\\bollywoodMovies.txt");
      //  this.noOfMovies = 20;
    }

}

public List<String> getList() {
    List<String> movieList = new ArrayList<>();
    String[] values = null;
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String line;
        while ((line = br.readLine()) != null) {
            values = line.split(";");
            movieList.add(values[0]);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return movieList;
}

public String getMovie(){
    System.out.println(movies.size());
    int min = 1;
    int max = movies.size();
    int random = min + (int) (Math.random() * (max - min));

    System.out.println(random);
    String title = movies.get(random);
    return title;
 }

}

MAIN CLASS

import java.util.Scanner;

public class Main {

  public static void main(String[] args) {

    System.out.println("Enter 'h' for hollywood and 'b' for bollywood ");
    Scanner input = new Scanner(System.in);
    char genre = input.next().charAt(0);
    Game newGame = new Game(genre);

    String randomMovie = newGame.getMovie();
    System.out.println(randomMovie);
 }
}

Note i've used List data structure in place of array but it is obviously up to you... let me know if this may look like what you are trying to do... some other improvements can certainly be made but should work.

Also it assumes you have a txt file with movie titles separated by semicolon...otherwise you have to adjust the split method in the getList one..

Furthermore this way you no longer need the noOfMovies field cause it takes automatically the list size.

Hope it helps...

Upvotes: 1

rghome
rghome

Reputation: 8819

The problem is that the fields are initialised before the constructor is called.

There are a number of things you should do:

  1. Don't call getters and setters from a constructor. See this question: Should I use getters and setters in constructors?

  2. If you are doing complex initialisation logic, do it all in the constructor. Only initialise fields directly with very basic values (not ones that depend other fields). In your case, it will be easier just to do everything in the constructor. This avoids the problem that you change your code to modify a value in the constructor and some field initialisation stops working.

Upvotes: 0

Related Questions