How can i avoid java.lang.NullPointerException error - java

I have some problem with my code.
First of all, here are my codes.
public class Zoo {
public int j=0;
public Animal[] park;
// Exercise 9
public Zoo() {
Animal[] park = new Animal[10];
}
// Exercise 10
public void addAnimal(Animal first) {
for (int i = 0; i < 10; i++) {
if (park[i] != null) {
park[i] = first;
i=j;
i = 10;
} else if (i == 9) {
System.out.println("The zoo is full!");
}
}
}
// Exercise 11
public void feed() {
for (int i = 0; i < 10; i++) {
park[i].mass *= 1.1;
}
}
public String toString() {
String result = "The list:\n";
for (int i = 0; i< 10; i++) {
result = result + "cage " + i + " status:" + park[i] + "\n";
}
return result;
}
public void print() {
System.out.println(park.toString());
}
public int totalLegs() {
int totalLeg = 0;
for (int i = 0; i < 10; i++) {
totalLeg += park[i].legs;
}
return totalLeg;
}
}
ALSO
public class Animal {
float mass;
String name;
int legs;
// Exercise 6-6
public Animal(String randomName) {
name = randomName;
legs = 0;
mass = 0;
}
// Exercise 6-7
public Animal(float one, String two, int three) {
mass = one;
name = two;
legs = three;
}
//Exercise 7
public String toString(){
return "name =" + name + "legs=" + legs + "mass=" + mass;
}
public void massSetter() {
}
public String getName() {
return name;
}
public int getLegs() {
return legs;
}
}
AND
public class TestZoo {
public static void main(String[] args){
Zoo zoo = new Zoo();
Animal elephant = new Animal(300f,"elephant",4);
Animal spider = new Animal(0.5f,"spider",6);
Animal snake = new Animal(10f,"snake",0);
zoo.addAnimal(elephant);
zoo.addAnimal(spider);
zoo.addAnimal(snake);
zoo.print();
System.out.println("Average number of legs is");
}
}
As you probably can tell from the code, I am very new to programming and when I run the last class (TestZoo.java), it gives me the following error.
Exception in thread "main" java.lang.NullPointerException
at Zoo.addAnimal(Zoo.java:13)
at TestZoo.main(TestZoo.java:9)
I did some searching and apparently I get this error when I try to pass a null as if it has something.
I looked at line 13 of the Zoo class and I honesty have no idea how to fix this.
Any help would be greatly appreciated.
Thanks in advance

This is the problem:
public Animal[] park;
public Zoo() {
Animal[] park = new Animal[10];
}
You're declaring an instance variable called park - but then in the constructor, instead of assigning a value to that instance variable, you're creating a local variable called park and assigning a value to that. Change your constructor to:
public Zoo() {
park = new Animal[10];
}
Or you could change the declaration to:
public Animal[] park = new Animal[10];
and remove the explicit constructor declaration entirely.
Either way, the instance variable park will be non-null when you call addAnimal.
Additionally, within addAnimal, there are various issues. For a start, you're continuing to look through park until you find a non-null entry, rather than until you find a null entry... which is the wrong way round.
There are various other things which I'd change about the code (e.g. keep fields private), but hopefully this is enough to get you going.

Within your constructor
public Zoo() {
Animal[] park = new Animal[10];
}
you have shadowed park, as such the instance variable park is never initialised
This means you have created annother variable park that happens to have the same name as the class variable
public class Zoo {
public int j=0;
public Animal[] park; <--This park
public Zoo() {
Animal[] park = new Animal[10]; <--In not the same as this park
}
To correct simply stop creating a new park within your constructor, so
public class Zoo {
public int j=0;
public Animal[] park; <--This park
public Zoo() {
park = new Animal[10]; <--Now is the same as the other park
}

Related

Setters And Getters to different Class

My problem is that, simply I don't know what code to use to get my value from my getX method to my other classses main method.
package hangman;
public class Hangman {
private int triesLimit;
private String word;
public void setTriesLimit(int triesLimit) {
this.triesLimit = triesLimit;
}
public void setWord(String word) {
this.word = word;
}
public int getTriesLimit() {
return this.triesLimit;
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
return ("Enter Secret Word " + this.getWord()
+ ".\nEnter max # of tries (Must be under 7) "
+ this.getTriesLimit());
}
}
Thats from the sub-class and I am trying to store the value of the triesLimit into the main of this classes main method
package hangman;
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
Scanner scn = new Scanner(System.in);
int triesCount = 0;
int correctCount = 0;
hangman.toString();
int triesLimit = hangman.getTriesLimit();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
for (int i = 0; i < secretWord.length(); i++) {
b.append("*");
}
char[] secrectStrCharArr = secretWord.toCharArray();
int charCnt = secretWord.length();
for (int x = 0; triesCount < triesLimit; triesCount++) {
while (charCnt >= 0) {
System.out.println("Secrect Word :" + b.toString());
System.out.println("Guess a letter :");
char guessChar = scn.next().toCharArray()[0];
for (int i = 0; i < secrectStrCharArr.length; i++) {
if (guessChar == secrectStrCharArr[i]) {
b.setCharAt(i, guessChar);
correctCount++;
} else if (guessChar != secrectStrCharArr[i]) {
triesCount++;
System.out.println("Incorrect: " + triesCount);hangmanImage(triesCount,correctCount);
}
}
}
}
}
I tried looking it up on here but couldn't find setters and getters used in a sub/superclass
You need to create an instance of the class in the main method to access the variables and method available in that class like so
public class PlayHangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setTriesLimit(2)
int value = hangman.getTriesLimit();
}
You can look into static keyword to access the value directly but that requires a bit more understanding of OOP's and JAVA.
This should work fine.
Hope it helps :)
EDITED
ToString method is just to convert everything in your model class to String which you have done correctly,but you have implemented incorrectly.... Change your ToString content so
#Override
public String toString() {
return ("The Secret Word you entered: " + this.getWord()
+ ".\n The max # of tries (Must be under 7): "
+ this.getTriesLimit());
}
You have initialized Scanner which does what you want, to ask the user to enter the values but again you haven't implemented it so add this to your main method
Scanner scn = new Scanner(System.in);
hangman.setTriesLimit(scn.nextInt());
hangman.setWord(scn.next());
hangman.toString()//Will work now
Trial and error is your best friend now :)
and Google some of the issues rather than waiting for an answer :)
Like rohit said, this is as simple as understand the basics of OOP, specific the encapsulation.
If you want to get a little deeper into OOP patterns, you could use the Observer pattern. This allows you to change the status of any class instance, even if they're not related by inheritance, aggregation, etc.
You can scale the solution by making List of Observer
Your observable interface
public interface IObservable {
// Set the observer
public void setObserver(IObserver iObserver);
// Notify the observer the current status
public void notifyObserver();
}
Your observer interface
public interface IObserver {
public void update(boolean status);
}
Your observer implementation
public class PlayHangman implements IObserver {
private boolean status = false;
public void printStatus() {
System.out.println("Status: " + (this.status ? "Win" : "Lose"));
}
#Override
public void update(boolean status) {
// The instance status is updated
this.status = status;
// Print the current status
this.printStatus();
}
}
Your observable implementation
public class Hangman implements IObservable{
private String goalWord = "";
private String currentWord = "";
private int triesLimit = 0;
private int tries = 0;
private IObserver iObserver;
public Hangman(String goalWord, int triesLimit) {
this.goalWord = goalWord;
this.triesLimit = triesLimit;
}
public void setCurrentWord(String currentWord) {
this.currentWord = currentWord;
this.notifyObserver();
}
public void addTry() {
this.tries++;
this.notifyObserver();
}
#Override
public void setObserver(IObserver iObserver) {
this.iObserver = iObserver;
}
#Override
public void notifyObserver() {
// True = win
this.iObserver.update(this.tries < this.triesLimit &&
this.goalWord.equals(this.currentWord));
}
}
Your Main class
public class Main{
public static void main(String[] args) {
// PlayHangman (game status)
PlayHangman playHangman = new PlayHangman();
// Hangman initializes with a goalWord and the triesLimit
Hangman hangman = new Hangman("HangmanJava", 5);
// Set the observer
hangman.setObserver(playHangman);
// During the game you just can set the current word and add a try
// You're not setting the status directly, that's the magic of the Observer pattern
hangman.setCurrentWord("Hang");
hangman.addTry();
hangman.setCurrentWord("HangmanJava");
}
}
Hope this helps and enjoy Java

How to add multiple instances of class in an array loop?

Main class is Zoo, Animal class performs Polymorphism by calling the pinStick method from each different Animal (other classes)
In the zoo array loop, int r's value is decided by Math.random which is 1 or 0 each time, resulting in a squeak, or a roar, depending which animal class is called.
My question is, how can I include an instance of the class Monkey to be printed every time the Mouse or Lion is called (in the if statement)
The aim is add a new instance of the monkey class so that in the result printout you have “OoOoAhAh” together with “Squeak” and “Roar”
public class Zoo {
private Animal[] animals;
public Zoo() {
animals = new Animal[10];
}
public void talkAnimals() {
int r;
for (int i = 0; i < 10; i++) {
r = (int) Math.round(Math.random());
if (r == 0) {
animals[i] = new Mouse();
} else{
animals[i] = new Lion();
}
}
for (int i = 0; i < 10; i++) {
animals[i].pinStick();
}
}
public static void main(String[] args) {
// TODO code application logic here
new Zoo().talkAnimals();
}
}
public class Animal {
protected String name;
public Animal(){
}
public void pinStick(){
}
}
public class Mouse extends Animal {
public void pinStick(){
System.out.print("Squeak!");
}
}
public class Monkey extends Animal {
public void pinStick(){
System.out.print("OoOoOoAhAhAh!");
}
}
public class Lion extends Animal {
public void pinStick(){
System.out.print("Roar!");
}
}
The aim is add a new instance of the monkey class so that in the result printout you have “OoOoAhAh” together with “Squeak” and “Roar”
You can just declare another array for Monkey
private Animal[] monkeys;
constructor
monkeys = new Monkey[10];
and pushes new Monkey object in for loop
for (int i = 0; i < 10; i++) {
r = (int) Math.round(Math.random());
if (r == 0) {
animals[i] = new Mouse();
} else{
animals[i] = new Lion();
}
monkeys[i] = new Monkey();
}
then later on in the for loop just do the printing job
for (int i = 0; i < 10; i++) {
animals[i].pinStick();
monkeys[i].pinStick();
}

How to let an Animal object know what Room it is in through a reference

I am working with two separate classes, Animal and Room. A Room is instantiated with an array within. Animal objects are then instantiated and placed in the array within the Room. How can I give the Animal objects a reference to what Room they are placed into so when I call a look() method on them, they can return the name of the Room they are in?
public static void main(String[] args) {
Room mainRoom = new Room("The Lobby");
Animal gizmo = new Animal("Gizmo");
mainRoom.addAnimal(gizmo);
System.out.println(mainRoom.toString());
gizmo.look();
}
-
public class Room {
private String name;
private Animal[] animals;
private Room currentRoom;
int i = 0;
public Room(String name) {
setName(name);
animals = new Animal[10];
}
public String toString() {
String temp = new String();
temp += "\nThis room is " + name + ".\n\n";
temp += "In the lobby are the following animals: \n";
for (Animal s : animals) {
temp += s.toString() + "\n";
}
return temp;
}
public void setName(String name) {
this.name = name;
}
public void addAnimal(Animal a) {
if (i < 10) {
if (animals[i] != null) {
i++;
addAnimal(a);
} else {
animals[i] = a;
}
} else {
System.out.println("Room full");
}
}
}
-
public class Animal {
private Room currentRoom;
private String name;
public Animal() {
}
public Animal(String name) {
setName(name);
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "\t" + name;
}
public void look() {
System.out.println(name + " is currently in " + getCurrentRoom());
//getCurrentRoom().toString();
}
public Room getCurrentRoom() {
return this.currentRoom;
}
public void setCurrentRoom(Room currentRoom) {
this.currentRoom = currentRoom;
}
}
How can I give the Animal objects a reference to what Room they are
placed into so when I call a look() method on them, they can return
the name of the Room they are in?
You should set the room within Animal instead:
Animal gizmo = new Animal("Gizmo");
gizmo.setCurrentRoom(mainRoom); // this would set mainRoom as the attribute of gizmo
Further your code here:
public void look() {
System.out.println(name + " is currently in " + getCurrentRoom());
//getCurrentRoom().toString();
}
would fetch the currentRoom as set by the code above.
I think the most elegant solution will be inside the addAnimal function of the Room like this
public void addAnimal(Animal a) {
if (i < 10) {
if (animals[i] != null) {
i++;
addAnimal(a);
} else {
animals[i] = a;
a.setCurrentRoom(this); // Setting room of animal
}
} else {
System.out.println("Room full");
}
}
gizmo.setCurrentRoom(mainRoom);
(If construct Animal object within Room use : gizmo.setCurrentRoom(this))
You could also add String getRoomName() {return currentRoom.getName();} to Animal class.

Creating an ArrayList of Employees

I have three classes
employee
production workers
shift supervisor class
My idea is to make production and shift supervisor extend the employee class and then create another class, EmployeeList to fill it with information about production workers and shift supervisors.
How can i get the names and info from employee class to iterate into an arraylist?
How can i add a random list of employees more than half being prod. workers and the rest shift supervisors?
Employee:
public class Employee {
public String EmployeeName;
public String EmployeeNumber;
public int hireyear;
public double WeeklyEarning;
public Employee()
{
EmployeeName = null;
EmployeeNumber = null;
hireyear = 0;
WeeklyEarning = 0;
}
public static final String[] Enum = new String[] {
"0001-A", "0002-B","0003-C","0004-D","0002-A",
"0003-B","0004-C","0005-D","0011-A", "0012-B",
"0013-C","0014-D","0121-A", "0122-B","0123-C" };
public static final String[] Ename = new String[] {
"Josh", "Alex", "Paul", "Jimmy", "Josh", "Gordan", "Neil", "Bob",
"Shiv", "James", "Jay", "Chris", "Michael", "Andrew", "Stuart"};
public String getEmployeeName()
{
return this.EmployeeName;
}
public String getEmployeeNumber()
{
return this.EmployeeNumber;
}
public int gethireyear()
{
return this.hireyear;
}
public double getWeeklyEarning()
{
return this.WeeklyEarning;
}
public String setEmployeeName(String EName)
{
return this.EmployeeName = EName;
}
public String setEmployeeNumber(String ENumber)
{
return this.EmployeeNumber = ENumber;
}
public int setEmployeehireyear(int Ehireyear)
{
return this.hireyear = Ehireyear;
}
public double setEmployeeweeklyearning(double Eweeklyearning)
{
return this.WeeklyEarning = Eweeklyearning;
}
}
ProductionWorker:
import java.util.Random;
public class ProductionWorker extends Employee {
public double HourlyRate;
public ProductionWorker()
{
super();
HourlyRate = 0;
}
public static void main(String[] args) {
ProductionWorker pw = new ProductionWorker();
Random rnd = new Random();
int count =0;
// adding random Employees.....
while(count<5)
{
int num= rnd.nextInt(Enum.length);
int decimal = rnd.nextInt(10);
double dec = decimal/10;
pw.setEmployeeName(Ename[num]);
pw.setEmployeeNumber(Enum[num]);
pw.setEmployeehireyear(rnd.nextInt(35) + 1980);
pw.setEmployeeweeklyearning(rnd.nextInt(5000) + 5000);
pw.setHourlyRate(rnd.nextInt(44) + 6 + dec);
System.out.println("EmployeeName: " + pw.getEmployeeName() + "\nEmployeeNumber: " + pw.getEmployeeNumber() +
"\nHireYear: " + pw.gethireyear() + "\nWeeklyEarning: " + pw.getWeeklyEarning() +
"\nHourlyRate: " + pw.getHourlyRate() +"\n");
count++;
}
}
public double getHourlyRate()
{
return this.HourlyRate;
}
public void setHourlyRate(double hourlyrate)
{
this.HourlyRate = hourlyrate;
}
}
ShiftSupervisor:
import java.util.Random;
public class ShiftSupervisor extends Employee{
public double YearlySalary;
public int GoalsCleared;
public ShiftSupervisor()
{
super();
YearlySalary = 0;
}
public static void main(String[] args) {
ShiftSupervisor S = new ShiftSupervisor();
Random rnd = new Random();
int count =0;
// adding random Employees.....
System.out.println("Adding Employees..");
while(count<5)
{
int num= rnd.nextInt(Enum.length);
S.setEmployeeName(Ename[num]);
S.setEmployeeNumber(Enum[num]);
S.setEmployeehireyear(rnd.nextInt(35) + 1980);
S.setEmployeeweeklyearning(rnd.nextInt(100) * 100);
S.setYearlySalary(rnd.nextInt(40000) + 40000);
System.out.println("EmployeeName:" + S.getEmployeeName() + "\nEmployeeNumber: " + S.getEmployeeNumber() +
"\nHireYear: " + S.gethireyear() + "\nWeeklyEarning: " + S.getWeeklyEarning() +
"\nearlySalary: " + S.getYearlySalary() +"\n");
count++;
}
}
// returns yearly salary
public double getYearlySalary()
{
return this.YearlySalary;
}
// returns goals cleared
public int getGoalsCleared()
{
return this.GoalsCleared;
}
// set yearly salary
public void setYearlySalary(double yearlysalary)
{
this.YearlySalary = yearlysalary;
}
}
The first thing I would do is have all necessary fields set in the constructor. If an Employee doesn't "exist" until it has a name, then that should be part of the constructor.
Then, I would suggest you consider renaming some of your fields. When I first saw Enum as a String[] and highlighted as a type, it took me a moment to figure out what exactly was going on. Renaming it to employeeNumbers could solve this.
Next, I think you should have an EmployeeGenerator class whose sole purpose is generating Employees.
public class EmployeeGenerator {
public ProductionWorker generateProductionWorker() {
Random rng = new Random();
int numberOfEmployeeNames = employeeNames.length;
String employeeName = employeeNames[rng.nextInt(numberOfEmployeeNames)];
int numberOfEmployeeNumbers = employeeNumbers.length;
String employeeNumber = employeeNumbers[rng.nextInt(numberOfEmployeeNumbers)];
ProductionWorker worker = new ProductionWorker(employeeName, employeeNumber);
int yearHired = rng.nextInt(100) + 1900;
worker.setHireYear(yearHired);
int hourlyRate = rng.nextInt(20) + 10;
worker.setHourlyRate(hourlyRate);
// any other fields...
return worker;
}
// method to generate shift supervisor
}
And then you can simply do
public static void main(String[] args) {
Random rng = new Random();
int numberOfEmployeesToGenerate = 1000;
int minimumNumberOfProductionWorkers = numberOfEmployeesToGenerate / 2;
int numberOfProductionWorkersToGenerate =
minimumNumberOfProductionWorkers + rng.nextInt(100);
int numberOfSupervisorsToGenerator =
numberOfEmployeesToGenerate - numberOfProductionWorkersToGenerate;
List<Employee> employees = new ArrayList<>();
EmployeeGenerator generator = new EmployeeGenerator();
for (int i = 0; i < numberOfProductionWorkersToGenerate; i++) {
ProductionWorker worker = generator.generateProductionWorker();
employees.add(worker);
}
for (int i = 0; i < numberOfSupervisorsToGenerate; i++) {
Supervisor supervisor = generator.generateSupervisor();
employees.add(supervisor);
}
}
This should hopefully give you a point in the right direction. This isn't perfect code, and there are other ways to refactor this to make it more maintainable and performant.
When you say you want to add a random list of employees, What do you mean exactly?
Currently you instantiate only one ProductionWorker and one ShiftSupervisor, change the values of the member variables, and print some text to StdOut.
Do you want to store instances in a list or is the console output sufficient?
Also, you have two main-methods. Which one will be performed? It might be better to have one Main class as an entry point for your application and from there create the instances.
In general you can do something like that:
public class Main {
public static void main(String[] args) {
List<Employee> emps = new ArrayList<>();
for (int i = 0; i < 5; i++) {
//create new employee
emps.add(newEmployee);
}
//do something with list
}
}

"Cannot instantiate the type...."

public class TestingClass {
public static void main(String[] args) {
int numberRooms = 6;
double totalSpace;
Room[] rooms = new Room[numberRooms];
rooms[0] = new Room(20, 20);
rooms[1] = new Room(20, 20);
rooms[2] = new Room(22, 20);
rooms[3] = new Room(20, 20);
rooms[4] = new Room(25, 20);
rooms[5] = new Room(15, 13);
Garage garage = new Garage(20, "Cement", 1, 20, 1, 4);
for (int i = 0; i < numberRooms; i++) {
totalSpace = totalSpace + calculateRoomSpace(rooms[i]);
}
System.out.println("Total room space is " + totalSpace);
foo(garage);
}
public static double calculateRoomSpace(Room roomSpace) {
double newRoomSpace = roomSpace.calcFloorSpace();
return newRoomSpace;
}
public static void foo(Building myBuilding) {
System.out.println("Total floor space is " + myBuilding.calcFloorSpace());
}
}
I put in this code and get the error
"Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot instantiate the type Garage
at TestingClass.main(TestingClass.java:17)"
what is the problem here exactly?
Edit
** Here is the Garage class**
abstract public class Garage extends Building {
private int cars;
private String floorType;
private int garageLength;
private int garageWidth;
public Garage(int floors, int windows, int cars, String floorType,
int garageLength, int garageWidth) {
super(floors, windows);
this.cars = cars;
this.floorType = floorType;
this.garageLength = garageLength;
this.garageWidth = garageWidth;
}
#Override
public double calcFloorSpace() {
int floorSize;
floorSize = garageLength * garageWidth;
return floorSize;
}
public int getCars() {
return cars;
}
public void setCars(int cars) {
this.cars = cars;
}
public String getFloorType() {
return floorType;
}
public void setFloorType(String floorType) {
this.floorType = floorType;
}
public int getGarageLength() {
return garageLength;
}
public void setGarageLength(int garageLength) {
this.garageLength = garageLength;
}
public int getGarageWidth() {
return garageWidth;
}
public void setGarageWidth(int garageWidth) {
this.garageWidth = garageWidth;
}
#Override
public String toString() {
return "Garage [cars=" + cars + ", floorType=" + floorType
+ ", garageLength=" + garageLength + ", garageWidth="
+ garageWidth + "]";
}
}
Hope this helps. Not an expert at this and have spent quite a while figuring this out. thanks
You can't instantiate an abstract class.
You've got two options:
Remove abstract from the class declaration, or
Create another class to extend Garage, which can be instantiated.
You cannot instantiate an instance of an abstract class. You either need to make your class concrete (remove the abstract modifier on the class and provide an implementation for all methods), or extend the abstract class to create a non-abstract class.
When you remove the abstract modifier, the compiler will tell you what abstract methods you are missing (if any).
Your Garage Class is declared as abstract class cannot be instantiated .Check this for more details Can an abstract class have a constructor?
Garage is an abstract class, so it cannot be instantiated. Only its subclasses can be instantiated.

Categories

Resources