I'm trying to run a program that will, if all goes well, be able to take a year and return the title of an album released in that year. I've given it 6 albums already and I'm now trying to actually print a title. I've fixed a few pretty frustrating errors, but this is one I've not seen before. The error appears at line 21, but I'm not sure what it means. Can anyone help?
package songselector;
import java.util.Scanner;
public class Main {
public class Album
{
int year; String title;
public Album () {
this.year = 0; this.title = null;
}
public Album (int year, String title) {
this.year = year; this.title = title;
}
}
class CAKE {
Album[] albums;
public CAKE () {
albums = new Album[6];
albums[0].year = 1994; albums[0].title = "Motorcade Of Generosity";
albums[1].year = 1996; albums[1].title = "Fashion Nugget";
albums[2].year = 1998; albums[2].title = "Prolonging The Magic";
albums[3].year = 2001; albums[3].title = "Comfort Eagle";
albums[4].year = 2004; albums[4].title = "Pressure Chief";
albums[5].year = 2011; albums[5].title = "Showroom of Compassion";
}
public void printAlbum (int y) {
System.out.println (albums[y].title);
}
}
public static void main(String[] args) {
new Main().new CAKE().printAlbum (0);
}
}
It means that you are trying to access / call a method on an object which is null. In your case, you initialized the array of Albums, but didn't initialize each of the albums in the array.
You need to initialize each album in the array:
albums = new Album[6];
albums[0] = new Album();
albums[0].year = 1994;
albums[0].title = "Motorcade Of Generosity";
...
Or even simpler (as #entonio pointed out):
albums = new Album[6];
albums[0] = new Album(1994, "Motorcade Of Generosity");
albums[1] = new Album(1996, "Fashion Nugget");
...
Since you have a proper constructor.
One more thing: don't call more than one method in each line, it will help you debugging.
When you allocate an array of objects, it's filled with null values. You need to create objects to fill them. Your albums[0] wasn't created, so trying to access its year field (even for writing) results in a NPE.
Related
I am writing a program to store certain Recipe info. into an array. Using method RecipeEntry(), with its parameters, the program is meant to store up to a maximum of 3 recipes into an array named: totalEntry[].
Below is my attempt at writing this program, however, I am getting errors .. unable to figure out what it is that I am missing.
import java.util.*;
public class RecipeArray
{
private String author;
private Recipe recpH_1;
private Recipe recpC_2;
private static RecipeEntry[] totalEntry = new RecipeEntry[3];
private static int entryCount;
public RecipeArray(String author, Recipe hot, Recipe cold) // constructor
{
entryCount = 0;
this.author = author;
recpH_1 = hot;
recpC_2 = cold;
totalEntry[entryCount] = new RecipeArray(author, recpH_1, recpC_2);
}
public static void main(String[] args)
{
RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
// RecipeEntry method, when called should pass its parameter values into
// totalEntry [] array. entryCount variable should keep count of every entry.
System.out.println("ALL ENTRY = " + entryCount + Arrays.toString(totalEntry));
}
}
public class Recipe //create class data of type recipe
{
private String name;
private int id, rating;
public Recipe(String name)
{
this.name = name;
id = 0;
rating = 0;
}
}
The expected output should print a list of the entries - Example:
Output:
index 0 - [Mary Bush, SpaghettiHOT{id=0, rating=0}, SpaghettiCOLD{id=0, rating=0}]
The problem is that you didn't catch the returned Array from your method:
RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
Actually the RecipeArray as you wrote will return an Array; it means that the method will pass and Array to it's caller.
Changing the mentioned line with the following line will solve the problem:
RecipeEntry[] totalEntry = RecipeEntry("Mary Bush", SpaghettiHOT, SpaghettiCOLD);
Visit https://www.tutorialspoint.com/importance-of-return-type-in-java for better understanding of Java Methods:
I have the following program:
class Books
{
String title;
String author;
}
class BookTestDrive
{
public static void main(String [] args)
{
Books [] myBooks = new Books[3];
int x = 0;
myBooks[0].title = "The Grapes of Java";
myBooks[1].title = "The Java Gatsby";
myBooks[2].title = "The Java Cookbook";
myBooks[0].author = "bob";
myBooks[1].author = "sue";
myBooks[2].author = "ian";
while (x < 3)
{
System.out.print(myBooks[x].title);
System.out.print(" by ");
System.out.println(myBooks[x].author);
x = x + 1;
}
}
}
However, it gives me the following error when I execute it:
Exception in thread "main" java.lang.NullPointerException
at BookTestDrive.main(Books.java:14)
I am new to Java. The code looks legitimate from my C/C++ experience...How to resolve this problem?
The issue is that you have only created the array of books in the following lines -
Books [] myBooks = new Books[3];
You still need to initialize each element in the array to a book object before accessing them.
An example code would look like -
Books [] myBooks = new Books[3];
int x = 0;
myBooks[0] = new Books();
myBooks[0].title = "The Grapes of Java";
You need to do this for all elements in your array.
I second the answer from #AnandSKumar (it is the direct answer to the problem after all), but because it is a matter of beauty, I could not leave without making following few changes:
public class Play {
static public class Book {
final public String title;
final public String author;
public Book(String title,String author) {
this.title = title;
this.author = author;
}
#Override
public String toString() {
return "\""+title+"\" by "+author;
}
}
public static void main(String [] args)
{
Book [] books = new Book[] {
new Book("The Grapes of Java","bob"),
new Book("The Java Gatsby","sue"),
new Book("The Java Cookbook","ian"),
};
for (Book book:books) {
System.out.println(book);
}
}
}
You can initialize in-line the content of your array
If you represent 'a single book' then we should name the class representing it as Book and not Books to avoid confusion.
We can enhance the Book class with an improved toString(), and use that instead.
There is a enhanced for iterator to loop over your array.
Note that the third position book in the array, also ends with a comma, although there is no element following it. This could have been a mistake, but it this case it was a deliberate choice. Makes it easier to copy-paste into next elements without introducing errors, as the Java syntax allows for it.
Because once a book is created, title and author should not change anymore, it might be good to design the Book class to be 'Immutable'. For this reason a constructor was added, and the title and author fields set as final. You could also consider making them private, and provide getters.
I have information like this:
xxx 0 1 2 ...
Name Fred0 Fred1 Fred2
Stamina 2 6 7
Intel 5 4 1
Heart 4 8 2
Speed 5 3 6
So, I was informed previously that creating a 2D ArrayList to store something like this is "archaic" and was provided with a different way to set my code up. The reason I was using ArrayList<> is because I want to be able to generate new racers as needed, rather than designating an array to a size. If I could just use a simple array this would have been done a week ago. Now I've been screwing with it for a week and I still don't get how it works.
public class test {
public String name;
private int stamina;
private int heart;
private int intel;
private int speed;
public ArrayList<String> racers = new ArrayList<String>();
private void racerInfo(String name) {
this.name = name;
this.stamina = (int) Math.floor(Math.random()*10);
this.heart = (int) Math.floor(Math.random()*10);
this.intel = (int) Math.floor(Math.random()*10);
this.speed = (int) Math.floor(Math.random()*10);
}
public void generate() {
for ( int i=0; i<=10; i++) {
String name = "Fred" + i;
System.out.println(name);
racerInfo(name);
racers.add(name);
}
}
public int getStamina() {
return this.stamina;
}
public int getHeart() {
return this.heart;
}
public int getIntel() {
return this.intel;
}
public int getSpeed() {
return this.speed;
}
}
public class main {
public static test test = new test();
public static void main(String[] args) {
test.generate();
//Put stuff here to pull stamina of Fred2 for example.
}
}
Now, in the main class. How would I do something that should be relatively simple like pulling the Stamina value for Fred2.
I've been following the exact directions I've been given by others here to write most of this code. But at this time, I'm getting to the point of just re-writing it all so that each stat (name, stamina, intel, speed, etc.) is just logged as a separate ArrayList<>. But I can't figure out how to make a 2D ArrayList containing the original ArrayLists ie.
ArrayList<String> name = new ArrayList<String>();
ArrayList<Integer> stamina = new ArrayList<Integer>();
ArrayList<ArrayList<Object>> arrayOfArray = new ArrayList<ArrayList<Object>>();
Yes, I know the arrayOfArray is probably done wrong, but, again, I just get told it's Archaic and nobody'll tell me how I can do it right so I can just go. arrayOfArray.get(2,1) and pull information that I want/need.
Sorry for the information overload here. but I'm trying to just find the best possible solution for what I want to do. If you can tell me how to correctly pull off either way I will be eternally grateful you you and all of your descendants.
First of you should refactor your class test to class Racer, which is a meaningful name and follows the convention to start classnames with an uppercase letter. Furthermore you should add Stamina, Intel, Heart and Speed to the constructor:
public Racer(String name, int stamina, int intel, int heart, int speed) {
this.name = name;
this.stamina = stamina;
this.intel = intel;
this.heart = heart;
this.speed = speed;
}
Now you can create your racer as following:
Racer fred2 = new Racer("Fred2", 7, 1, 2, 6);
You can store your values in a HashMap. HashMap is a collection consisting of key-value pairs. For the key you can use a string (the name of the racer) and as value you take an instance of your class Racer:
HashMap<String, Racer>() racerMap = new HashMap<>();
racerMap.put("Fred2", fred2);
This you can do in a for-loop for all of your racers. Now you can get the racer objects from your HashMap by calling the getMethod and putting the name as parameter in it. This will return an object of class Racer and you can call the getter methods on this object:
racerMap.get("Fred2").getSpeed();
or
racerMap.get("Fred2").getIntel();
Edit: I just saw your generate method. This method should return the HashMap of racers. In your main method you create a new HashMap:
HashMap<String, Racer> racerMap = generate();
Now you can use the map as described above.
I'm having an issue when I want to set the name of an object to another class, because I keep receiving the NullPointerException, and I'm not quite sure how to fix this error.
Here is an example:
First Class:
//Just excuse the Vehicle class, it's just an example
private Vehicle[] car;
private int number = 1;
private int count = 0;
public store Display()
{
car = new Vehicle[number];
}
public void setVehicleName(String name)
{
car[count].setName(name);
}
public String getVehicleName()
{
return car[count].setName(name);
}
Second class:
//So, I have radio buttons, so I'll just skip to that code
if (addName.equals(e.getActionCommand()))
{
name = JOptionPane.showInputDialog(null, "Enter the vehicle name: "); //there is a private String name
name.toLowerCase(); //automatically converted to lower case
displayStore.setVehicleName(name); //assume an Display object called 'displayStore'
}
So, if anybody has an idea or know how's to fix it, I would be grateful. Thanks!
Arrays of objects in java come default set to null so if you do
Vehicle [] car = new Vehicle[number];
car[1].setName("Toyota");
You will get a NullPointerException because car[1] is null
You need to initialize the array. So likely you will want to do this in your constructor
public store Display()
{
car = new Vehicle[number];
for(int i=0;i<number;i++) {
car[i] = new Vehicle();
}
}
You need to instantiate car[count] before using it. So, replace your Display method with this:
public store Display()
{
car = new Vehicle[number];
for(int i = 0; i < count; i++)
car[i] = new Vehicle();
//Return some store type object here or change the type to void
// Moreover it is better to do initialization/instantiation in the constructor, rather
// than a separate method
}
I have a class called AgendaFunctions, a class called Main, and a class called ReadFiles. Main has a reference variable for Agenda Functions and ReadFiles. AgendaFunctions has an array of reference variables. I have code to instantiate the array, but i need to instantiate it from ReadFiles. If I instantiate it from main, it works fine. But if i call the method from ReadFiles, it doesn't work. I get a java.lang.NullPointerException error.
Here is the code for Main:
public class Main {
public static void main(String[] args) throws Exception {
ReadFiles fw = new ReadFiles(); fw.read();
agendafunctions link = new agendafunctions();
AgendaFunctions:
public class agendafunctions {
int amount = 20;
public void setamount(int data) {
}
static String input = "true";
agendaitem item[] = new agendaitem[amount];
int counter = 0;
public void instantiate() {
item[1] = new agendaitem();
item[2] = new agendaitem();
item[3] = new agendaitem();
}
public void createobject(String name, Boolean complete, String Comments) {
item[counter].name = name;
item[counter].complete = complete;
item[counter].comments = Comments;
counter++;
}
ReadFiles:
public class ReadFiles {
public void read() throws IOException {
agendafunctions af = new agendafunctions(); af.instantiate();
int readitem = 1;
BufferedReader data = new BufferedReader(new FileReader("C:/Agenda Dev Docs/data.txt"));
int filestoread = Integer.parseInt(data.readLine());
while (readitem <= filestoread) {
String name;
String complete;
String comments = null;
String line;
Boolean bc = null;
BufferedReader read = new BufferedReader(new FileReader("C:/Agenda Dev Docs/"+readitem+".txt"));
readitem++;
name = read.readLine();
complete = read.readLine();
comments = "";
while((line = read.readLine()) != null) {
comments = comments + line;
}
if(complete.equals("Complete")) {
bc = true;
} else if(complete.equals("Incomplete")) {
bc = false;
}
af.createobject(name, bc, comments);
}
}
If I call the method instantiate from ReadFiles, i get a NullPointerException. If I call it from Main, everything works. But further development requires me to call the method from ReadFiles. How would i fix this? Thanks.
You have this
int counter = 0;
public void instantiate() {
item[1] = new agendaitem();
item[2] = new agendaitem();
item[3] = new agendaitem();
}
public void createobject(String name, Boolean complete, String Comments) {
item[counter].name = name;
item[counter].complete = complete;
item[counter].comments = Comments;
counter++;
}
where item is an array with 20 indices, ie 20 elements, but your instantiate method only initializes elements at indices 1 through 3, missing 0 and 4 through 19.
In your ReadFiles#read() method, you do
agendafunctions af = new agendafunctions(); af.instantiate();
which instantiates one agendafunctions object and calls instantiate() which initializes elements at indices 1, 2, and 3 in your item array.
You then loop in the while and call
af.createobject(name, bc, comments);
a bunch of times on the same object.
The reason it fails the first time is because you haven't initialized the element in item at index 0. Arrays always start at 0, not 1.
Another cause for error (which you'll see if you fix the above problem), is that if your while loop loops more than 3 times, you'll again get a bunch of NullPointerExceptions because counter keeps growing, but you aren't initializing the elements that you'll then try to access at counter index.
item[counter].name = name; // if counter is 4, you'll get NullPointerException because
// the element there hasn't been initialized as 'new agendaitem();'
#SotiriosDelimanolis explained why you are getting NPE, to fix that you just can get rid of the instantiate() method and add item[counter] = new agendaitem(); as first line in your createobject method. Also you have to make sure your while loop does not exceed amount. To avoid these worries better use an ArrayList for agendaitem