Java: NPE calling a method on an array element - java

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
}

Related

Can I use public void from a class to make use of it in ArrayList to add age and name?

I'm new to Java and I'm trying to get my head around constructs, classes and objects. I apologise if any of this seems stupid to you.
I have been tasked with creating an ArrayList to hold items of type Data (my class). using the .add method - I should add a certain number of names and ages then output.
I have sort of done it, but I was wondering if I could use the functions like SetAge and SetAge from my class to use within my ArrayList to create a new person and then output it together like I have with the rest. Is there another way?
Thank you for your help & explanation.
Below is my code;
import java.util.ArrayList;
public class workingOn {
public static void main (String[] args)
{
Data Fred = new Data("Fred", 21);
Data Jo = new Data("Jo", 43);
Data Zoe = new Data("Zoe", 37);
ArrayList<Data> myArray = new ArrayList<Data>();
myArray.add(Fred);
myArray.add(Jo);
myArray.add(Zoe);
for (Data temp : myArray)
{
System.out.println(temp.toString());
}
}
}
Below is my class;
public class Data {
private String name;
private int age;
Data(String n,int a)
{
name = n;
age = a;
}
public String GetName()
{
return(name);
}
public void SetName(String n)
{
name = n;
}
public int GetAge()
{
return(age);
}
public void SetAge(int a)
{
age = a;
}
public void Print()
{
System.out.print(("("+ GetName() ));
System.out.print(",");
System.out.print(GetAge());
System.out.print(") ");
}
//i made this so I don't output the object id
public String toString() {
return (name + ", " + age);
}
}
Going through the comments, I am guessing you want to somehow use the setter methods (setName() and setAge()) for the class that you have designed. The easiest way would be:
Data d = new Data("tempName", 10);
myArray.add(d);
This basically creates an object of type Data and adds it to the arraylist. Let's assume that you want to change the name and age of this person you just added, then you should do this:
myArray.get(myArray.size() - 1).setName("newName");
myArray.get(myArray.size() - 1).setAge(18);
To add some explanation, when you add an object to an arraylist, it always adds in the end. We use size() method to get the number of objects in the Arraylist. Since index starts from 0, we use myArray.size() - 1. We use the .get() method to retrieve the object from the arraylist which takes a number as a parameter and return the object at that index.
Combining these two, we get the object at the last possible index, and call the setName() and setAge() function on it.
Hope this helps.

Java - Inheritance regarding constructors

So, I'm trying to practice my java skills by applying it to some math homework and making a frequency distribution chart using inheritance. In my head, I envision it as a frequency distribution (parent class = FreqDist) that can have multiple "MyStatClasses" (in the form of the MyStatClass array). Each FreqDist has variables that span across all MyStatClasses which is why I put them in the parent class. However, when I call the MyStatClass constructor, my program gets a StackOverflowError. I think this is because the super(s, i) line calls back to the FreqDist constructor and starts over, causing an infinite loop. Assuming this is the case, how would I fix this?
Ideally, I'd like to access my MyStatClass array and grab values that only apply to that MyStatClass, but I cannot get it to work.
public class FreqDist {
private MyStatClass[] freqClasses;
private double[] dblValuesArray;
private int intNumberOfClasses;
private double dblMax;
private double dblMin;
private int intClassWidth;
public FreqDist(String strValues, int intNumOfClasses) {
System.out.println("This is the beginning of the FreqDist constructor...");
dblValuesArray = getDoubleValues(strValues);
intNumberOfClasses = intNumOfClasses;
dblMin = dblValuesArray[0];
dblMax = dblValuesArray[dblValuesArray.length - 1];
intClassWidth = (int)Math.ceil((dblMax - dblMin) / intNumberOfClasses);
freqClasses = new MyStatClass[intNumberOfClasses];
for (int x = 0; x < freqClasses.length; x++) {
freqClasses[x] = new MyStatClass(strValues, intNumOfClasses);
}
}
public double[] getDoubleValues(String strValues) {
String[] strValuesArray = strValues.trim().split(" ");
dblValuesArray = new double[strValuesArray.length];
for (int x = 0; x < strValuesArray.length; x++) {
dblValuesArray[x] = Double.parseDouble(strValuesArray[x]);
}
Arrays.sort(dblValuesArray);
return dblValuesArray;
}
public int getNumberOfClasses() {
return intNumberOfClasses;
}
public double getMin() {
return dblMin;
}
public double getMax() {
return dblMax;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("What are the values? ");
String values = scan.nextLine();
System.out.print("How many classes? ");
int classes = scan.nextInt();
FreqDist fd = new FreqDist(values, classes);
}
}
public class MyStatClass extends FreqDist {
public MyStatClass(String s, int i) {
super(s, i);
}
}
Ok so this is mostly an issue with a flaw in your design.
From what I understand FreqDist is a class that should contain an array of MyStatClass. You want them to have the same properties so you make MyStatClass extend FreqDist. However when you call FreqDist it MyStatClass which Calls a new MyStatClass over and over and over.
One way to solve this is to create a new class that has the shared properties you want FreqDist and MyStatClass to have, and have those two classes inherit from said class. Then create separate constructors for FreqDist and MyStatClass.
A parent type should never refer to its own subtypes, as yours does. Her the parent initializes subtype instances, which require that each initialize the parent type, which initializes subtype instances, which initialize their parent type, which initializes... KABLOOEY!

How do I print my an array in a toString() method?

I'm trying to print an array via toString() so I can call it to another method. What exactly am I doing wrong? Why isn't it compiling and what is a better solution.
public class Applicants
{
private String applicant[];
public Applicants()
{
Application student1 = new Application()
Application student2 = new Application()
Application student3 = new Application()
Application student4 = new Application()
Application student5 = new Application()
Application student6 = new Application();
Application applicant[] = new Application[5];
applicant[0] = student1;
applicant[1] = student2;
applicant[2] = student3;
applicant[3] = student4;
applicant[4] = student5;
applicant[5] = student6;
for (int index = 0; index < applicant.length; index++)
{
System.out.println(applicant[index]);
}
}
public String toString(String[] applicant)
{
String output = new String();
String total;
for (int index = 0; index < applicant.length; index++)
{
total = System.out.println(applicant[index]);
}
return total;
}
}
There are three things wrong, and one "hey, pay attention".
You are shadowing your field applicant inside of your constructor. What this means is when you're done with your constructor, your String[] is null. Not full of null, just null.
What you probably meant to do was declare private Application[] applicant as your field, then not redeclare it inside of your constructor.
total = System.out.println(applicant[index]); is not a valid statement. You cannot assign the result of a void method to anything. You have it right in your constructor, so it's surprising that you didn't get it correct down here.
toString does not take any arguments. Use your field.
Please have toString defined on your Application object, as that will make your life easier. Otherwise, extract meaningful information from that object. You're going to do some string concatenation on this one in either event, which I leave as an exercise for the reader.
You need to declare the toString method in the Application class:
public class Application {
#Override
public String toString() {
// your code here
}
}
Note the use of the Override annotation. This will make the compiler check that you are actually overriding the method you say you are - in your current code, you are not as toString does not take any parameters.
As for implementation of toString, I would go with Google Guava
#Override
public String toString() {
return MoreObjects.toStringHelper(this.getClass()).add(..).add(..).toString();
}
See here for more info: https://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained
Guava docs

Editable 2D Array

I want to create a 2D Array that creates a mini seating chart of an airplane. So far, I've gotten it to successfully print out something that looks like this:
1A(0) || 1B(0) || 1C(0)
2A(0) || 2B(0) || 2C(0)
3A(0) || 3B(0) || 3C(0)
4A(0) || 4B(0) || 4C(0)
The zeroes represent an empty seat, and the number one is used to represent an occupied seat.
I first created the program with arrays that were class variables for a First Class, but I wanted to make this program usable for an Economy Class section. The only difference between the two sections is the size of the array so I edited my code to look like this:
public class Seating
{
private int FIRSTCLASS= 12;
private int ECONOMYCLASS= 240;
private int occupied, column;
private String[][] seatchart;
private int[][] seatlist;
private String[][] namelist;
private String name;
public String customer;
public Seating(String seatclass)
{
seatclass.toUpperCase();
if (seatclass.equals("FIRSTCLASS"))
{
seatchart= new String[FIRSTCLASS/3][3];
seatlist= new int[FIRSTCLASS/3][3];
namelist= new String[FIRSTCLASS/3][3];
}
else
if (seatclass.equals("ECONOMY"))
{
seatchart= new String[ECONOMYCLASS/3][3];
seatlist= new int[ECONOMYCLASS/3][3];
namelist= new String[ECONOMYCLASS/3][3];
}
}
public void Creation()
{
for (int i=0; i< seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
seatlist[i][j]= 0 ;
}
}
I get an null pointer exception error around for (int i=0; i< seatlist.length; i++)
How can I fix this error?
Thanks in advance!
The problem is with this line:
seatclass.toUpperCase();
Replace it with:
seatclass = seatclass.toUpperCase();
I think you are creating the class with a string like "firstclass" rather than "FIRSTCLASS" right? Those aren't the same strings and just invoking the toUpperCase method on the string without assigning the result to a variable to then be tested means nothing happens.
Then since none of your if conditions are met, the arrays are not initialized and a null pointer exception is thrown when Completion() is called.
I'm not sure if you are new to java programming, but I wanted to add a few recommendations to your class:
public class Seating {
private static int FIRSTCLASS= 12; // Make these constants static since they pertain to all
private static int ECONOMYCLASS= 240; // instances of your class. That way there is exactly on
// copy of the variables, which is more memory efficient.
private int occupied;
private column; // Okay but Java convention is to declare each member variable on its own line
// increases code readability.
private String[][] seatchart;
private int[][] seatlist;
private String[][] namelist;
private String locSeatClass;
private String name;
public String customer; // Okay but better to leave this private and then provide getter and
// setter methods to provide access to this string. Much easier to track
// down who is changing its value in your code.
public Seating(String seatclass) { // Java convention is to place the opening bracket here not
// on the next line.
// Make sure that seatClass is not null or empty. NOTE: This is a neat trick for
// simultaneously checking for both null and empty strings in one shot. Otherwise, you have
// you have to check for null and then examine the string's length which is more code.
if ("".equalsIgnoreCase(seatClass) {
throw new IllegalArgumentException("Seat class undefined.");
}
// Store the seat class in a member variable for use. Could also be a local variable.
// My original solution is problematic because it changes the original value of the seat
// class that was passed into the constructor (you might want that information).
locSeatClass = seatclass.toUpperCase();
if (locSeatClass.equals("FIRSTCLASS"))
{
seatchart= new String[FIRSTCLASS/3][3];
seatlist= new int[FIRSTCLASS/3][3];
namelist= new String[FIRSTCLASS/3][3];
}
else if (locSeatclass.equals("ECONOMY")) {
seatchart= new String[ECONOMYCLASS/3][3];
seatlist= new int[ECONOMYCLASS/3][3];
namelist= new String[ECONOMYCLASS/3][3];
}
else {
// Throw an exception if someone passes in an unknown seat class string.
throw new IllegalArgumentException("Unknown seat class detected.")
}
}
public void creation() { // NOTE: Java convention is to begin method names with a lower
// case letter.
// This method is unnecessary. Arrays of integers are initialized with an initial value
// of zero by default. However, if you want to make your class reusable, you could change
// change the name of the this method to clear, which would allow you to clear the arrays of
// an existing object.
for (int i=0; i< seatlist.length; i++)
{
for (int j=0; j<seatlist[i].length; j++)
{
seatlist[i][j]= 0 ;
}
}
}
The only way that line of code can generate a NPE is if seatlist is null. Unless you assign null to seatlist somewhere else in your class, the only way it can be null is if the argument that you pass to the Seating constructor does not match either "FIRSTCLASS" or "ECONOMY". Check your call to the constructor. Also, you might want to just use seatclass.equalsIgnoreCase().
You should modify your constructor to at least warn about that eventuality, since it is vital to the proper operation of the class that any instances of Seating have valid seatlist and namelist arrays.

Casting inner objects in java - unchecked exception

I'm having a problem with inner classes. I build an object (let's say a train) with an inner class representing states (let's say the stops of the train).
I'm trying to run this code:
private void CustomObjectBuilder (String [] origin) {
final int array_dim = origin.length;
InnerCustomObject[] tmp_bin = new InnerCustomObject[array_dim];
for (int ii = 0; ii < array_dim; ii++) {
String debug = extractData(origin[ii]);
tmp_bin[ii].setData(debug);
}
}
It compiles just just fine but at runtime I get a null object exception.
What am I doing wrong?
Here you can finde the original code:
public class CustomObject {
InnerCustomObject [] stops;
public class InnerCustomObject {
String name, station, schedTime, depTime, schedRail, depRail;
public void setData (String origin) {
this.station = origin;
}
}
}
Edit: I solved by calling
CustomObject.InnerCustomObject ico = new CustomObject(). new InnerCustomObject();
why it needs to be so verbose?
Well, the most immediate thing I notice is you don't populate tmp_bin[] with any objects after you declare it. When you first create an array, all it contains are nulls.
So when you do this in your loop:
tmp_bin[ii].setData(debug);
There is nothing to invoke setData() on, resulting in the exception.
Re edit: you can just do
InnerCustomObject ico = this.new InnerCustomObject();
since you're creating them within your outer CustomObject class's CustomObjectBuilder() instance method.
InnerCustomObject[] tmp_bin = new InnerCustomObject[array_dim];
declares an array of array_dim elements but all are null. Then this
tmp_bin[ii].setData(debug);
won't work.
No problem with inner classes only with an object that is null (=NPE) so you cannot call the method setData().
In your loop you have to create new instance of InnerCustomObject. By new InnerCustomObject[size] you do not create new instances.

Categories