-2

So I'm doing a project on Arrays using 2 classes and a tester class but I keep getting a nullPointerException error. I know what the error means essentially and I believe the problem lies in my Tank class provided below and its constructor to be more specific. The Tank class uses my class Fish and is supposed to create an array of fishes, and the tester then creates a new Tank object.

public class Fish{

  private int weight;
  private String name;

  public Fish(int w, String n){
    weight = w;
    name = n;
  }

  public void feed(){
    weight = weight + 5;
  }

  public int getWeight(){
    return weight;
  }

  public void setWeight(int w){
    weight = w;
  }

  public void setName(String n){
    name = n;
  }

  public String getName(){
    return name;
  }

  public void starve(){
    weight = weight -5;
  }

  public String toString(){
    return name +"'s weight is: " + getWeight();
  }
}

Here is the Tank class:

import java.util.ArrayList;
public class Tank{

  private boolean isFish = true;
  private int size;
  private int index = 0;
  private Fish[] fishArray;
  private ArrayList<Fish> fishTank = new ArrayList<Fish>();

  public Tank(int i){
   fishArray = new Fish[i];
  }

  public Tank(){
    fishArray = new Fish[10];
  }

  public void feedFish(int i){
    fishArray[i].feed();
  }

  public void addFish(Fish f){
    fishArray[index] = f;
    size++;
  }

  public void starveFish(int i){
    fishArray[i].starve();
  }

  public String getNameFor(int i){
    return (fishArray[i].getName());
  }

  public int getWeightFor(int i){
    return (fishArray[i].getWeight());
  }

  public int getTotalWeight(){
    int w = 0;
    for(int i =0; i< fishArray.length; i++){
      w = fishArray[i].getWeight() + w;
    }
    return w;
  }

  public Fish getLargest(){
    int heaviest = Integer.MIN_VALUE;
    for(int i = 0; i < fishArray.length; i++){
      if (fishArray[i].getWeight() > heaviest)
        heaviest = fishArray[i].getWeight();
      index = i;
    }
    return fishArray[index];
  }

  public Fish getSmallest(){
    int small = Integer.MAX_VALUE;
    for(int i = 0; i < fishArray.length; i++){
      if (fishArray[i].getWeight() < small)
        small = fishArray[i].getWeight();
      index=i;
    }
    return fishArray[index];
  }

  public boolean doesExist(Fish f){
    for(int i = 0; i < fishArray.length; i++){
      if(fishArray[i].getWeight() == f.getWeight() && fishArray[i].getName().equalsIgnoreCase(f.getName()))
        isFish = true;
      else isFish = false;
    }
    return isFish;
  }

  public ArrayList<Fish> transfer(){
    for(int i = 0; i < fishArray.length; i ++){
      fishTank.add(fishArray[i]);}
    return fishTank;
  }
}

as you can see, I am trying to build an overloaded constructor inside the tank class that creates an Array of fish objects but I'm having some trouble getting it to work. I believe that this is where my error is coming from in my tester class:

public class TankTest{
  public static void main(String[] args) {

    Tank tank = new Tank();
    tank.addFish(new Fish(10, "Doris"));
    tank.addFish(new Fish(12, "Marlin"));
    tank.addFish(new Fish(7, "nemo"));
    tank.addFish(new Fish(15, "bubbles"));
    tank.addFish(new Fish(18, "gill"));
    tank.addFish(new Fish(5, "peach"));

    tank.feedFish(3);
    tank.starveFish(2);
    tank.starveFish(4);
    tank.feedFish(5);
    tank.starveFish(1);
    tank.feedFish(0);
    tank.feedFish(2);
    tank.starveFish(5);
    tank.starveFish(1);
    tank.feedFish(3);
    tank.feedFish(1);
    tank.feedFish(5);
    tank.starveFish(0);



    System.out.println("The total weight is : " + tank.getTotalWeight());
    System.out.println("The largest Fish is : " + tank.getLargest().getName() );
    System.out.println("The smallest Fish is : " + tank.getSmallest().getName() );

    tank.transfer();

  }
} 

Any help would be appreciated

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 3
    The exception message tells you at what line the exception is thrown. That will help to pinpoint what variable or object is null. It will also help us help you. – DCON Sep 29 '17 at 23:53
  • 3
    The NullPointerException would have printed the line number. That is crucial information for debugging! – tanyehzheng Sep 29 '17 at 23:53
  • Damn I knew I forgot something. Here's the error code: java.lang.NullPointerException at Tank.addFish(Tank.java:23) at TankTest.main(TankTest.java:5) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:267) – cavermendes Sep 29 '17 at 23:57
  • 1
    @cavermendes Should edit the question and isolate the line that exception is happening on. Then it should be pretty obvious – Sam Orozco Sep 29 '17 at 23:58
  • The heuristic for debugging a NullPointerException is almost always the same: You should critically read your exception's stacktrace to find the line of code at fault, the line that throws the exception, and then inspect that line carefully, find out which variable is null, and then trace back into your code to see why. You will run into these again and again, trust me. In the future, please search on the subject before posting, since this is too common a problem to post yet another NPE question. – Hovercraft Full Of Eels Sep 30 '17 at 00:57
  • Check that Tank object at the line which triggers the exception is not null. Check all the objects (including arrays) used in addFish() method is not null. Simple as that. – user3437460 Sep 30 '17 at 01:44

1 Answers1

0

I noticed that you have an issue on your addFish method:

public void addFish(Fish f){
    fishArray[index] = f;
    size++;
}

So your code should be like this:

public void addFish(Fish f){
    fishArray[index] = f;
    index++;
    size++;
}

You should increment the index variable too. Currently, you are adding all your Fish object in the 0 position of your array.

You should also use the size variable instead of fishArray.length to avoid reaching null elements of your array. This variable should be initialized as 0 in your constructors same as for index variable.

You have instantiated 6 object (fish) but the array has 10 elements which 4 of them was not instantiated.

public Tank(){ 
  fishArray = new Fish[10];
}

this will create 10 fish in fishArray

fishArray[0] = new fish()
fishArray[1] = new fish()
...
fishArray[5] = new fish();

but

fishArray[6] = null
fishArray[7] = null
fishArray[8] = null
fishArray[9] = null

try to change getTotalWeight(), getLargest() and getSmallest() to :

public int getTotalWeight(){
    int w = 0;
    for(int i =0; i< size; i++){
        w = fishArray[i].getWeight() + w;
    }
    return w;
  }

  public Fish getLargest(){
    int heaviest = Integer.MIN_VALUE;
    for(int i = 0; i < size; i++){
        if (fishArray[i].getWeight() > heaviest) {
           heaviest = fishArray[i].getWeight();
           index = i;
        }            
    }
    return fishArray[index];
  }

  public Fish getSmallest(){
    int small = Integer.MAX_VALUE;
    for(int i = 0; i < size; i++){
        if (fishArray[i].getWeight() < small) {
           small = fishArray[i].getWeight();
           index=i;
        }            
    }
    return fishArray[index];
  }
Mohamed Chaawa
  • 918
  • 1
  • 9
  • 23
  • Thanks a lot Mohamed. Changing the fishArray.length inside the methods to size and adding index++ to the addFish method seemed to do the trick. The tester is now running like its supposed to be with no errors. – cavermendes Sep 30 '17 at 08:09
  • Perfect, can you check this answer as correct? – Mohamed Chaawa Sep 30 '17 at 19:37