Why do I keep getting a Null Exception Error? - java

I have three classes in my program. Ship.java, Cabin.java and Passenger.java. According to the program a single cabin can hold upto a maximum of 3 passengers. I'm trying to set passenger details but i keep getting this error
Cannot invoke "classes.Passenger.setFirstName(String)" because
"classes.Main.myShip[0].passenger[0]" is null at
classes.Main.main(Main.java:22)
Ship.java
public class Ship
{
public static Scanner scanner = new Scanner(System.in);
public static Cabin[] myShip = new Cabin[12];
public static void main(String[] args)
{
for (int count = 0; count < 12; count++)
{
myShip[count] = new Cabin();
}
myShip[0].passenger[0].setFirstName("a");
}
}
Cabin.java
public class Cabin
{
int cabinNumber;
Passenger[] passenger = new Passenger[3];
public Cabin()
{
}
public Cabin(int cabinNumber, Passenger[] passenger)
{
this.cabinNumber = cabinNumber;
this.passenger = passenger;
}
public void setCabinNumber(int cNumber)
{
cabinNumber = cNumber;
}
public int getCabinNumber()
{
return cabinNumber;
}
}
Passenger.java
public class Passenger
{
String firstName;
String lastName;
int expenses;
public Passenger()
{
}
//Constructors
public Passenger(String cabinFirstName, String cabinLastName, int pExpenses)
{
firstName = cabinFirstName;
lastName = cabinLastName;
expenses = pExpenses;
}
public void setFirstName(String cabinFirstName)
{
firstName = cabinFirstName;
}
public String getFirstName()
{
return firstName;
}
public void setLastName(String cabinLastName)
{
lastName = cabinLastName;
}
public String getLastName()
{
return lastName;
}
public void setExpenses(int pExpenses)
{
expenses = pExpenses;
}
public int getExpenses()
{
return expenses;
}
}
Please be kind enough to help me out.

Your model is wrong. A ship can (and does) have cabins with no occupants. You have provided no way to have unoccupied cabins. Your cabins need to be fully booked before the ship can be built!
I would consider redefining your Cabin class to be constructed empty -- which means it would have a constructor with a signature like Cabin(), and then provide a way to assign Passengers to Cabins. Maybe this would be a method in the Cabin class, like
boolean assignPassenger(Passenger p) {
... check occupancy...
... return false if full up ...
... otherwise add 'p' to the passenger array ...
... and return true ...
}
You're halfway there in that you're attempting to set the Cabins in the Ship by using a Cabin() constructor -- which is essentially an empty Cabin -- but you have not actually implemented a constructor with that signature.
What I'm getting at here is that, rather than just tweaking some Java, I think you should rethink it a bit. You'd want, I think, to be able to have unoccupied cabins and to be able to determine which cabins are occupied.

Related

How to write a toString method for ArrayList?

I am having a hard time finding out how to write my toString Method to get the output of each of my bears in my program. I want the output to show "Race - Points - TotalPoints". But can't manage to get it right even though the rest of the code seems to compile.
Do i need to have the toString defined in both classes or what am I missing? I have checked a couple of other questions that are resembling and that seems to be an alternativ? But how is it most effectively implemented?
First off the bear class:
import java.util.ArrayList;
public class Bear {
public static void main(String[] args) {
Bear b = new Bear("Sebastian", 100, "Brownbear");
ArrayList <Bear> bears = new ArrayList<Bear>();
bears.add(b);
}
private String name;
private int points;
private String race;
public Bear(String name, int points, String race) {
this.name = name;
this.points = points;
this.race = race;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRace() {
return race;
}
public void setRace(String race) {
this.race = race;
}
public int getInitialPoints() {
return points;
}
public int getPoints() {
int oldPoints = points;
points /= 2;
return oldPoints;
}
}
Secondly the BearCollection class:
import java.util.ArrayList;
public class BearCollection {
ArrayList <Bear> bears = new ArrayList<Bear>();
int totalPoints = 0;
public void add (Bear b) {
for (Bear inCollection : bears) {
if(b.getName().equals(inCollection.getName())) {
return;
}
}
for (Bear inCollection : bears)
if (b.getRace().equals(inCollection.getRace())) {
for(int i = bears.size(); i > 0; i --) {
if(bears.get(i).getRace().equals(b.getRace())) {
b.getPoints();
i = 0;
}
}
}
totalPoints += b.getInitialPoints();
bears.add(b) ;
}
public String toString(){
return ;
}
As you were told, just override the toString method. For performance use StringBuilder, rather than String concatenation.
import java.util.*;
public class ans{
public static void main(String[] args){
Bears bears = new Bears();
bears.add(new Bear());
bears.add(new Bear());
bears.add(new Bear());
System.out.println(bears);
}
}
class Bear{
public String toString(){
return "I am a bear";
}
}
class Bears{
private ArrayList<Bear> bears = new ArrayList<Bear>();
public void add(Bear bear){
bears.add(bear);
}
public String toString(){
StringBuilder str = new StringBuilder();
if(!bears.isEmpty()){ // If there is no bears, return empty string
str.append(bears.get(0)); // Append the first one
for(int index = 1; index < bears.size(); index++){ // For all others
str.append(" - "); // Append a separator and the bear string
str.append(bears.get(index));
}
}
return str.toString();
}
}
Edit To print A-B-C-D, just associate every item with a separator except one. A(-B)(-C)(-D) or (A-)(B-)(C-)D. You could add easily a beginning and a end mark.
overriding the toString in Bear class would resolve the issue.
If you need to print out the entire collection of Bears, you'd need to give Bear a toString, something like:
return "Bear("+name+","+points+","+race+")";
Then, in the toString of BearCollection, just write a for each loop in the toString to go through and call toString on each bear in the collection, printing them out.

My comparator class is not working

Ok, I have an object with multiple instance variables that I would like to sort by, so I read that i have to implement a comparator class and use it.
Basically its a plane class with PlaneSeats object as its member.
PlaneSeats has SeatID, CustomerID
I wish to print the occupied seats by CustomerIDs, does anyone know how?
//This Prints it by SeatID (Since it starts from 0)
for (int i = 0; i < seat.length; i++) {
if (seat[i].isOccupied()) {
System.out.println("SeatID " + seat[i].getSeatID() + " assigned to CustomerID " + seat[i].getCustomerID());
}
}
my failed Comparator code is as follows: I hope to NOT use a seperate class though, hopefully so sort of array.sort function?
import java.util.*;
public class Comparator implements Comparator<Plane> {
public int compare(Plane CustomerID[], Plane CustomerID[]) {
}
}
Arrays.sort(CustomerID, new Comparator<Plane>() {
public int compare(Plane p1, Plane p2) {
PlaneSeat ps1 = p1.getPlaneSeat();
PlaneSeat ps2 = p2.getPlaneSeat();
return ps1.getSeatID().compareTo(ps2.getSeatID());
}
});
This will sort on basis of SeatId. If you want to sort on basis of CustomerId, replace getSeatID() with getCustomerID().
This won't compile
public class Comparator implements Comparator<Plane> {
public int compare(Plane CustomerID[], Plane CustomerID[]) {
}
}
You are breaking the contract.
See this code for a possible solution.
PlaneSeat class definition
public class PlaneSeat {
//Create your custom comparator strategy
public static final Comparator<PlaneSeat> CUSTOMER_COMPARATOR = new CustomerComparator();
//fields
private final Integer customerID;
public PlaneSeat(Integer customerID){
this.customerID= customerID;
}
private static class CustomerComparator implements Comparator<PlaneSeat>{
#Override
public int compare(PlaneSeat o1, PlaneSeat o2) {
return o1.customerID.compareTo(o2.customerID);
}
}
#Override
public String toString() {
return "PlaneSeat [customerID=" + customerID + "]";
}
}
Plane class
public class Plane{
private List<PlaneSeat> seats;
public List<PlaneSeat> getSeats() {
return seats;
}
public void setSeats(List<PlaneSeat> seats) {
this.seats = seats;
}
public void sortSeatsByCustomer(){
Collections.sort(seats,PlaneSeat.CUSTOMER_COMPARATOR);
}
#Override
public String toString() {
return "Plane [seats=" + seats + "]";
}
}
Then in your client code:
public static void main(String args []){
List<PlaneSeat> seats = new ArrayList<>();
for(int i =10;i>0;i--)
seats.add(new PlaneSeat(i--));
Plane plane = new Plane();
plane.setSeats(seats);
System.out.println(plane);//print before sorting
plane.sortByCustomers();
System.out.println(plane);//after sorting by customer
}
You shouldn't name your class "Comparator", since that's already a Java interface name.
Plane CustomerID[]
This does not make sense.
Didn't I answer your prior question about seats?
Your PlaneSeat class should implement Comparable<PlaneSeat> and a method named
public int compareTo(PlaneSeat seat)
In this method, seat is the second seat, the object you're comparing with. The other object is
this
In this method, you can call the
getCustomerID()
method on the objects. It should look like:
public int compareTo(PlaneSeat seat) {
if (this.getCustomerID() > seat.getCustomerID()) return 1;
if (this.getCustomerID() < seat.getCustomerID()) return -1;
return 0;
}
If this gives you the reverse order of what you wanted, swap 1 and -1.
Before your comment
//This Prints it by SeatID (Since it starts from 0)
call
seat = Arrays.sort(seat);
to sort the seats.
You can't implement Comparator class again, it's defined as an interface and you have to implement it by naming a different class.

How to invoke a method of a superclass using the same method name in a subclass

I'm kind of confused on overriding a method in the super class. Can anyone help me on solving this problem that is bolded? I'm not exactly sure how to invoke the method 'say' in the main method of "basketball."
A basket ball team has 12 players. Each player is one of 3 types - center, guard, forward.
A team has 4 centers, 4 forwards, and 4 guards.
Each player has a unique name and a unique number.
Define a base class Player. A Player class has a name member, a string, and a number member, an integer.
Derive a Center class, a Guard class and Forward class from the Player class.
Define appropriate constructors, accessors and mutators for the base class and derived classes.
Define a base class method, Say. Says displays the player's name and number
Override the base class Say method in the derived classes.
The derived classes' Says display the player's position and invoke the base class Say.
Together, the base class Say and the derived class Says display a player's name, number, and type
public class Player
{
protected String firstName;
protected String lastName;
protected int num;
public Player(String first, String last, int jerseyNum)
{
firstName = first;
lastName = last;
num = jerseyNum;
}
public void setFirstName(String first)
{
firstName = first;
}
public String getFirstName()
{
return firstName;
}
public void setLastName(String last)
{
lastName = last;
}
public String getLastName()
{
return lastName;
}
public void setNum(int jerseyNum)
{
num = jerseyNum;
}
public int getNum()
{
return num;
}
public void say()
{
System.out.printf("The player's name is %s %s and his jersey number is %d.\n", firstName, lastName, num);
}
}
public class Center extends Player
{
private String center;
public Center(String first, String last, int num, String position)
{
super(first, last, num);
center = position;
}
public void setPosition(String position)
{
center = position;
}
public String getPosition()
{
return center;
}
#Override
public void say()
{
System.out.printf("This player plays the %s position", center);
}
}
public class Forward extends Player
{
private String forward;
public Forward(String first, String last, int num, String position)
{
super(first, last, num);
forward = position;
}
public void setPosition(String position)
{
forward = position;
}
public String getPosition()
{
return forward;
}
#Override
public void say()
{
System.out.printf("This player plays the %s position", forward);
}
}
public class Guard extends Player
{
private String guard;
public Guard(String first, String last, int num, String position)
{
super(first, last, num);
guard = position;
}
public void setPosition(String position)
{
guard = position;
}
public String getPosition()
{
return guard;
}
#Override
public void say()
{
System.out.printf("This player plays the %s position", guard);
}
}
public class basketball
{
public static void main(String[] Args)
{
//Player bballPlayer = new Player("Jon", "Jones", 25);
Center positionCenter = new Center("Jon", "Jones", 25, "Center");
positionCenter.say();
}
}
You can call a super classes method using super. as shown in the example shown below:
#Override
public void say() {
super.say();
System.out.printf(" This player plays the %s position", guard);
}
You would need to call the super method in the Player class, by doing something like this:
#Override
public void say()
{
super.say();
System.out.printf("This player plays the %s position", center);
}

Having trouble removing a specific element from a linked list

I have been set an assignment to create a small register based program written in Java, in the form of a linked list. I started by creating a student class, and then a tester file for the class. Following that, in the registry file I have set out my methods, and a constructor, and am in the process of writing a tester file to test all my methods.
However I am having trouble when trying to remove a specific element from my linkedlist, I want to be able to remove a student, referencing them by their individual studentID, but am not sure how to do this.
Whilst trying to solve the problem I came across the removeFirstOccurrence(Object o) method. Is this the right method to use?
Any help would be much appreciated.
STUDENT FILE CODE:
public class Student {
private String foreName;
private String surName;
private int studentID;
//declaring the variables needed for my student
public Student (String foreName, String surName, int studentID)
{
this.foreName = foreName;
this.surName = surName;
this.studentID = studentID;
}
//constructor to set out what a student needs
public String getForeName() {
return foreName;
}
public String getSurName() {
return surName;
}
public int getStudentID() {
return studentID;
}
public void setForeName(String foreName) {
this.foreName = foreName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
// getters and setters for my variables
public String toString ()
{
return getClass().getName() + "foreName = " + foreName + "surName = " + surName + "studentID = " + studentID;
}
//my toString method
}
REGISTRY FILE CODE:
import java.util.*;
public class Registry {
LinkedList<String> studentList
= new LinkedList<String>();
//setting my type parameter
public Registry() {}
//empty constructor to hold arguements
public void addStudent(String aStudent)
{
this.studentList.addLast(aStudent);
}
public void deleteStudent(int studentID)
{
//????
}
#Override public String toString()
{
return "Registry";
}
public String format()
{
}
REGISTRY TESTER FILE CODE:
import java.util.*;
public class RegistryTester {
public static void main (String[] args)
{
LinkedList<String> studentList
= new LinkedList<String>();
System.out.println("Test 1");
System.out.println("Methods tested: addStudent, constructor");
System.out.println("********************");
studentList.add("Joe Perkins 123");
studentList.addLast("Shilpa Gupta 1234");
studentList.addLast("Seany Ray 12345");
// adding 3 students to my list
System.out.println(studentList);
}
}
Define the List as a List of Student
LinkedList<Student> studentList = new LinkedList<Student>();
Override the hashCode() and equals() method in Student class.
public boolean equals(Object obj) {
if (obj instanceof Student) {
return studentID == ((Student)obj).getStudentID();
}
return false;
}
public int hashCode() {
return studentID;
}
Define methods:
public void addStudent(Student aStudent)
{
this.studentList.addLast(aStudent);
}
public void deleteStudent(Student astudent)
{
this.studentList.remove(aStudent)
}
First you should make your LinkedList for type Student:
LinkedList<Student>
Then to remove a student, you could :
go through the list, find out the student object with same id, remove it
override equals() and hashcode() method in your Student class, then
public void deleteStudent(int studentID)
{
//getStudent object (stu) By the given ID
studentList.remove(stu);
}
use Map, (HashMap or LinkedHashMap) instead of LinkedList, key is the studentId, value is the studentObject. This will make add/remove easier.
If you have a Collection (in your case a LinkedList) of Students and call remove(studentToRemove) on it, Java will compare each object with studentToRemove by using its equals() method.
In your case, you haven't written an equals() method, hence the one for Object is used. If indeed a student is uniquely identified by its studentId (that is, two Student instances with the same studentId are always the same student) you should override the equals() metod and check for equality using that field.
Read about equals() and hashCode().
Another alternative would be to iterate the list until you find the match, and then remove the student from the list.

Why am I getting this error when adding object to ArrayList - Java

I am trying to add objects to my ArrayList friends... I get this error,
The method add(int, Person) in the type ArrayList is not
applicable for the arguments (int, String)
I am trying to add a few instances of my person object to eventually create a tree of friends.
import java.util.*;
public class Person
{
public int id; // some identification number unique to the person
public boolean zombie; // true if the person is a zombie
public char state; // p means human, z means zombie
public static ArrayList<Person> friends; // list of friends
public Person(int id, char state)
{
this.id = id;
this.state = state;
//this.zombie = zombie;
}
public static void addPeople()
{
friends = new ArrayList<Person>();
friends.add(1, 'p');
}
public boolean isZombie()
{
if (state == 'p')
{
return zombie=false;
}
else if (state == 'z')
{
return zombie=true;
}
return zombie;
}
}
The error is located under the "add" word. I would also like to know how I can name the instances of the object so I only call the name rather than the two attributes.
Thanks in advance for all help.
import java.util.ArrayList;
import java.util.List;
/**
* Person description here
* #author Michael
* #link http://stackoverflow.com/questions/15799429/why-am-i-getting-this-error-when-adding-object-to-arraylist-java/15799474?noredirect=1#comment22468741_15799474
* #since 4/3/13 9:45 PM
*/
public class Person {
private Integer id;
private boolean zombie;
private List<Person> friends;
public static void main(String [] args) {
List<Person> lastPeopleStanding = new ArrayList<Person>();
for (int i = 0; i < 3; ++i) {
lastPeopleStanding.add(new Person(i));
}
lastPeopleStanding.get(0).addFriend(lastPeopleStanding.get(1));
lastPeopleStanding.get(0).addFriend(lastPeopleStanding.get(2));
System.out.println(lastPeopleStanding);
}
public Person(Integer id) {
this.id = id;
this.zombie = false;
this.friends = new ArrayList<Person>();
}
public boolean isZombie() { return this.zombie; }
// Irreversible! Once you go zombie, you don't go back
public void turnToZombie() { this.zombie = true; }
// Only add a friend if they're not a zombie
public void addFriend(Person p) {
if (p != null && !p.isZombie()) {
this.friends.add(p);
}
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Person{");
sb.append("id=").append(id);
sb.append(", zombie=").append(zombie);
sb.append(", friends=").append(friends);
sb.append('}');
return sb.toString();
}
}
You forgot to create a new Person to add to your ArrayList:
From your comment, you can create a class member variable called idCount and increment when a Person is added:
public void addPeople() {
friends.add(new Person(++idCount, 'p'));
}
Using static methods is generally considered poor design for a class that can have state.

Categories

Resources