So I have a bunch of classes used for an animal hospital. My superClass, Pet, has four constants, MALE, FEMALE, SPAYED, NEUTERED, that are set to numbers. When a data file is read in, in my AnimalHospitalClass, it is supposed to set the gender to a number, go back to the Pet class compare the "sexId" to the constant, and then return the gender. The issue Im having is not logical but technical. For some reason my setter is (setSex(sexID)) is getting the number that my gender is set to, but when I try to make the if statements in my getter to compare the numbers and return the gender, the sexID ( which is a variable in the Pet class) is set back to 0, instead of what I set it to.
heres my Pet Class:
public class Pet{
private String petName;
private String ownerName;
private String color;
protected int sexID;
public static final int MALE = 1;
public static final int FEMALE = 2;
public static final int SPAYED = 3;
public static final int NEUTERED = 4;
public Pet(String petName, String ownerName, String color){
this.petName = petName;
this.ownerName = ownerName;
this.color = color;
}
// getters
public String getPetName(){
return petName;
}
public String getOwnerName(){
return ownerName;
}
public String getColor(){
return color;
}
public String getSex(){
/* this is where I am having issues, instead of sexID being set to what
it is in the setter, it is set back to 0*/
System.out.println("SEXID: " + sexID); // will print 0
if(sexID == MALE){
return("male " );
}
else if(sexID == FEMALE){
return("female");
}
else if(sexID == SPAYED){
return("spayed");
}
else if(sexID == NEUTERED){
return("neutered");
}
else{ // will print else only since sexID is equal to 0
return("Not Available. " + sexID);
// in case there is no gender in the file
}
}
public void setSex(int sexID){
this.sexID = sexID;
System.out.println("SEX: " + sexID); // this will print the correct
// sexID that was set in the other class
}
public String toString(){
return(petName + "owned by " + ownerName
+ "\nColor: " + color
+"\nSex: " + getSex() );
}
}
here is my Animal hospital class (only one method since it is large):
import java.util.*;
import java.io.*;
public class AnimalHospital{
Scanner input;
private String pName;
private String pName2;
private String oName;
private String color ;
private String specialType; // store hair length for cats, size for dogs
private String gender;
private String type; // finds CAT, DOG, BIRD
public AnimalHospital(String inputFile)throws FileNotFoundException{
input = new Scanner(new File(inputFile));
}
public void printPetInfoByOwner(String name){
Pet pet = new Pet(pName,oName,color);
while(input.hasNext()){
String type = input.next(); // finds Cat, Dog, Bird
pName = input.next(); // gets pet name
oName = input.next(); // gets owner name
color = input.next();
gender = input.next();
if(gender.equals("male")){ // this is where I set the gender
int male = 1; // to a number so I can compare
pet.setSex(male);
}
if(gender.equals("female")){
int female = 2;
pet.setSex(female);
}
if(gender.equals("spayed")){
int spayed = 3;
pet.setSex(spayed);
}
if(gender.equals("neutered")){
int neutered = 4;
pet.setSex(neutered);
}
if(!(type.equals("BIRD"))){
specialType = input.next(); // since Bird does not have a special type
}
if(type.equals("CAT") && oName.equals(name)){
Cat cat = new Cat(pName, oName, color, specialType);
System.out.println(cat.toString());
break;
}
if(type.equals("DOG") && oName.equals(name)){
Dog d = new Dog(pName, oName, color, specialType);
System.out.println(d.toString());
break;
}
if(type.equals("BIRD") && oName.equals(name)){
Bird b = new Bird(pName, oName, color);
System.out.println(b.toString());
break;
}
}
}
here is an example output:
CAT: Busker owned by Samantha
Color: Black
Sex: Not Available. 0 // reads sex as 0 should be 2, and female
Hair: short
AnimalHospital#55f96302 // also how do I get rid of this?
Note:
This is an assignment, and I understand if you don't want to give me the answer, any hints would be helpful, but I've thought about this for days and can't figure it out.
thanks!
You're setting the sex on the pet variable, of type Pet. Then you create a Cat, Bird or Dog, never set its sex, and print it. So, since you never set the sex of the Cat, Bird or Dog, it's 0.
Related
I am learning JAVA OOP, I have to compare the age between 2 objects:
In java Procedural, I will have done:
public static int calculateDifferenceAge(int agePlayer1, int agePlayer2){
int differenceAge = agePlayer1 - agePlayer2;
if(differenceAge < 0){
differenceAge = -differenceAge;
}
return differenceAge;
}
Then
public static void displayDifferenceAge(String namePlayer1, String namePlayer2, int agePlayer1, int agePlayer2){
System.out.println("Age difference between " + namePlayer1 + " and " + namePlayer2 + " is of" + calculateDifferenceAge(agePlayer1, agePlayer2) + " year(s).");
}
}
I don't understand how to create my calculateDifferenceAge() method in OOP ?
In my main file I have this:
List<Player> players = new ArrayList <Player>();
players.add(new Player("Eric", 31, true));
players.add(new Player("Juliette", 27, false));
I am stuck into my 2 methods:
How to subtract the age of 2 objects?
public static int calculateAgeDifference(List <Player> players){
Player differenceAge = (players.get(0) - players.get(1));
return differenceAge;
}
public static void displayCalculateAgeDifference(List <Player> players){
System.out.println(calculateAgeDifference().age);
}
Class Player
public class Player {
public String name;
public int age;
public boolean sex;
public Player(String name, int age, boolean sex){
this.name = name;
this.age = age;
this.sex = sex;
}
you're only missing a little step in your code. The steps to extract the ages of the list should be:
1.- Extract the object from the list
2.- Extract the age of that object (or player, in this case)
3.- Substract the ages
There's some ways to do it, but I would do it this way:
public static int calculateAgeDifference(List<Player> players) {
int age1= players.get(0).age;
int age2= players.get(1).age;
int differenceAge = age1 - age2;
if(differenceAge < 0){
differenceAge = -differenceAge;
}
return differenceAge;
}
I hope that helps. What i've done there is extract the objects player from the list: players.get(0) extracts the first object inside the list, which is a Player. Now that I have a player and it has an age variable i have to extract it with player.age. I collapsed those steps, if you have any questions I can explain you further
Display method:
public static int displayCalculateAgeDifference (List<Player> players){
String name1= players.get(0).name;
String name2= players.get(1).name;
//as you know this method return the difference in a number form
int difference= calculateAgeDifference(players);
System.out.println("Age difference between " + name1 + " and " + name2 + " is of" + difference + " year(s).");
}
Let's start with a class Player. Let's give it a name and an age, and a calculateAgeDifference method. It should look something like,
public class Player {
private int age;
private String name;
public Player(String name, int age) {
this.name = name;
this.age = age;
}
public int calculateAgeDifference(Player player2) {
return Math.abs(this.age - player2.age);
}
}
Then you can call it like
Player a = new Player("Eric", 40);
Player b = new Player("Sally", 51);
System.out.println(a.calculateAgeDifference(b));
You must have a similar Player class. Yours appears to also have a boolean field. It isn't clear why. So I can't speak to that.
Why did your method interface change from two parameters to a list? You can still pass two instances of the object. You can still return the integer age value from the method, no need to create a Frankenstein's Player instance only to hold the age.
I am assuming your Player class has a method getAge() to extract the age value which was passed in in the constructor:
public static int calcAgeDiff(final Player player1, final Player player2) {
int age1 = player1.getAge();
int age2 = player2.getAge();
return Math.abs(age2 - age1);
}
Alternatively, you can add an instance method to your Player class itself to calculate the age difference to a different player:
public class Player {
// fields
// constructor
// getters
public int ageDiffTo(final Player otherPlayer) {
return Math.abs(this.age - otherPlayer.age); // <- a class can always access its private fields, even of other instances
}
}
then call as player1.ageDiffTo(player2)
I'm working on a program that reads data (of type string and int) from a file. Then, it creates an object named Person and puts it into an ArrayList.
For this task I am using the Scanner.
With methods like next(), nextLine(), I'm able to read/parse the data and create Person; however, I don't really know how to handle the situation when the input will have mixed persons.
My task says that there could be 2 options (input can include):
name, yearOfBirth
or, name,yearOfBirth,carName and Color (r,g,b)
Option 1: With next(), nextLine(), I know (more or less) how to do it:
John 1980 Mercedes 255 255 102
In the ArrayList, John should look like [John 1980 Mercedes 255 255 102]
but I do not know what to do when input will be for ex.:
Option 2:
John 1980 Mercedes 255 255 102
Mary 1997
Alice 1993 Skoda 0 127 153
In this situation, the program should recognize that the Mary do not have a car and in the ArrayList. Mary will look like [Mary 1997 null]
So, class Person has 2 constructors:
public Person(String name, int yearOfBirth, Car car)
and
public Person(String name, int yearOfBirth)
and Overrided toString() method.
Main:
public class Main {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
File file = new File("file.txt");
Scanner sc;
try {
sc = new Scanner(file);
while (sc.hasNext()) {
// here, i think, i should create an Person and add 'him/her' to ArrayList<Person>
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println(list);
System.out.println("End of Program.");
}
}
Person class:
public class Person {
String name;
int yearOfBirth;
Car car;
public Person(String name, int yearOfBirth, Car car) {
super();
this.name = name;
this.yearOfBirth = yearOfBirth;
this.car = car;
}
public Person(String name, int yearOfBirth) {
super();
this.name = name;
this.yearOfBirth = yearOfBirth;
}
#Override
public String toString() {
return name + " " + yearOfBirth + " " + car;
}
Car class:
public class Car {
String nameCar;
Color color;
int r, g, b;
public Car(String nameCar, int r, int g, int b) {
this.nameCar = nameCar;
this.color = new Color(r, g, b);
this.r = r;
this.g = g;
this.b = b;
}
#Override
public String toString() {
return nameCar + " " + r + " " + g + " " + b;
}
}
Input should includeArrayList of Persons
for this example you can read the whole line with your scanner, using sc.nextLine() (also use sc.hasNextLine() on the while loop). Then you can get the fields on a string array like this:
String line = sc.nextLine();
String[] fields = line.split(" ");
//separate all the "words" in the string by a space character
After doing this you can test if the length of the fields array is 6 =, meaning that the person has a car or only 2.
I cannot figure out how to format the code for my if-statements. Typically, I would take a string input from the user and use .equals, however the object I am required to use makes that impossible. Whenever I print the contents of the array, I get references. I want to get a user input stored to be stored in the array and printed in a later line of code.
Question: If possible, how do I get a scanner input to be assigned to a "Team" and referenced for comparison in the if-statements? How should I go about assigning these values?
Here is the code I was given
public class Team implements Comparable<Team> {
public String toString(String team, int wins) {
String winningStatement = team + ": " + wins;
return winningStatement;
}
// Data fields
private String name;
private int winCount;
Team() {
name = "Sooners";
winCount = 1;
}
Team(String inputName) {
name = inputName;
winCount = 1;
}
Team(String inputName, int inputWinCount) {
name = inputName;
winCount = inputWinCount;
}
Here is my attempt at using an ArrayList
Scanner scnr = new Scanner(System.in);
Random rando = new Random();
String name = "hi";
int cycles = 0;
int value = 0;
ArrayList<Team> teams = new ArrayList<Team>();
Team myTeam = new Team();
System.out.println("Welcome to the Advanced Sportsball Tracker!");
while (!name.equals("x")) // looping print statement
{ // x loop begins
System.out.println("Which team just won? (x to exit)");
name = scnr.next();
if (!teams.equals(name))
{
teams.add(thisTeam);
myTeam.setWinCount(1);
}
else if (teams.equals(name))
{
myTeam.incrementWinCount();
}
cycles++;
}// x loop ends
Thank you for the assistance
Judging only by the intent of your example... it appears that this is what you are trying to achieve. As stated though, your question of how ArrayList objects relate to overloaded constructors does not really make sense
public class Team {
// Data fields
private String name;
private int winCount;
public Team() {
name = "Sooners";
winCount = 1;
}
public Team(String inputName) {
name = inputName;
winCount = 1;
}
Team(String inputName, int inputWinCount) {
name = inputName;
winCount = inputWinCount;
}
public String toString(String team, int wins) {
return team + ": " + wins;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getWinCount() {
return winCount;
}
public void setWinCount(int winCount) {
this.winCount = winCount;
}
void incrementWinCount() {
winCount++;
}
}
void runSystem() {
List<Team> teams = new ArrayList<>();
Scanner scnr = new Scanner(System.in);
int cycles = 0;
System.out.println("Welcome to the Advanced Sportsball Tracker!");
System.out.println("Which team just won? (x to exit)");
String name = scnr.next();
while (!"x".equals(name)) {
final String teamName = name;
Team team = teams.stream().filter(t -> teamName.equals(t.getName())).findAny().orElse(null);
if (team == null) {
team = new Team(teamName, 1);
teams.add(team);
}
else {
team.incrementWinCount();
}
cycles++;
System.out.println("Which team just won? (x to exit)");
name = scnr.next();
}
}
So recently I've got into this problem, that every time I try to add two+ cars(trucks, busses or vehicles) program gets null pointer reference. Seems like my array can only hold one object. Why is that? Array size is set to 200... Adding one object works like a charm. This also works on C#. But not in Java.
public class Town {
public int MaxNumberOfCars = 200;
public String Dealership;
public String Adress;
public String Phone;
public Car[] Cars = new Car[MaxNumberOfCars];
public Bus[] Busses = new Bus[MaxNumberOfCars];
public Truck [] Trucks = new Truck[MaxNumberOfCars];
public Vehicles[] Vehicles = new Vehicles[MaxNumberOfCars];
public static int carCount;
public static int busCount;
public static int truckCount;
public static int vehicleCount;
public int townVehicleCount;
public int DealershipCount;
public double avgage;
public Town(String dealership, String adress, String phone) {
Dealership = dealership;
Adress = adress;
Phone = phone;
}
public void AddCar(Car car) {
Cars[carCount++] = car;
vehicleCount++;
}
The code where I'm accesing the AddCar:
private static void Read(String text, Town[] towns) {
String text1 = text;
String dealership = null, adress = null, phone = null;
ArrayList<String> line = new ArrayList<>();
StringTokenizer st = new StringTokenizer(text1, "\n");
int count = st.countTokens()-3;
if (line != null) {
dealership = st.nextToken();
adress = st.nextToken();
phone = st.nextToken();
towns[townCount] = new Town(dealership, adress, phone);
for(int i = 0; i < count; i++) {
String string = st.nextToken();
String[] values = string.split(";");
String licenseplates = values[0]; // 004
char type = values[1].charAt(0);
String brand = values[2];
String model = values[3];
YearMonth yearofmake = YearMonth.parse(values[4]);
YearMonth techinspection = YearMonth.parse(values[5]);
String fuel = values[6];
int fuelconsumption = Integer.valueOf(values[7]);
switch (type) {
case 'c':
Car car = new Car(licenseplates, brand, model, yearofmake, techinspection, fuel, fuelconsumption);
towns[townCount].AddCar(car);
towns[townCount].AddVehicle(car);
break;
}
townCount++;
}
}
}
Your problem is that you are incrementing townCount without there being enough towns in your array towns. You need to either add more towns to your array, or delete the townCount++; line at the end of your for loop.
Why your count variables are static?
I think first you must change this. then you must add some validation like checking MaxNumberOfCars validation in your addCar method.
My question today is, how can I assign values for my state variables/methods, in order to compare values to determine the winner?
Also, how do I direct the values to "Jack" and "Jill" (player p1 and p2)?
Should I use if-else statements?
And last question: why does my console print "null" for my getScore, getcardSuit, getcardValue, etc??
(I will give you my console printout after all of this)
Here is my code for my "player class", and my "tester" project is below this code (to test my player class):
public class player {
// The two players are going to enter:
String p1[] = {"Jack", "h", "k"};
String p2[] = {"Jill", "d", "9"};
//Setting up values
String Jack = "Jack";
String Jill = "Jill";
String h = " Hearts ";
String d = " Diamonds ";
String k = " King ";
int val = 9;
// Score
public int score = 0; // State variable score, set equal to 0
// Player name - Jack, Jill
public player(String Jack, String h, String k) {
// TODO Auto-generated constructor stub
}
public String playerName(String player)
{
player = "Jack";
player = "Jill";
return player;
}
// Card suit
public String cardSuit(String getcardSuit)
{
return cardSuit;
}
// Card Value for player 1
public String getCardValue()
{
return cardValue;
}
public String getScore(String score)
{
return score;
}
public String player;
public String playerName;
public String cardSuit;
public String cardValue;
public double getScore;
public String getCardSuit()
{
return cardSuit;
}
public int getScore() {
return 0;
}
}
Here is my "Tester", to test my "player class":
public class Tester {
public static void main(String[] args) {
// Create an object for player 1
player p1 = new player("Jack", "h", "k");
// Create an object for player 2
player p2 = new player("Jill", "d", "9");
// Use p1 object and methods getCardSuit and getCardValue to report p1's card
System.out.println(p1.playerName+"'s card is a "+p1.getCardValue()+" of "+p1.getCardSuit()+".");
// Should print:
// Jack's card is a King of Hearts.
// Use p2 object and methods getCardSuit and getCardValue to report p2's card
System.out.println(p2.playerName+"'s card is a "+p2.getCardValue()+" of "+p2.getCardSuit()+".");
// Should print:
// Jill's card is a 9 of Diamonds.
// Compare player's scores to determine winner
if(p1.getScore()>p2.getScore())
System.out.println(p1.playerName+" is the winner!");
else if (p1.getScore()<p2.getScore());
System.out.println(p2.playerName+" is the winner!");
// Should print:
// "Jack is the winner!"
}
}
CONSOLE:
null's card is a null of null.
null's card is a null of null.
null is the winner!
how can I fix this "null" stuff and actually have their values printed??
Thanks so much, in advance! :)
I'll start by answering the question you asked:
The values are null because they were never initialized. Your constructor for the player class:
public player(String Jack, String h, String k) {
// does absolutely nothing with the values.
}
does nothing. This means you created a new player player1 and a new player player2 but didn't actually use the values to do anything at all.
player p1 = new player("Jack", "h", "k");
calls the constructor, sends in values and the values are ignored. An instance of player1 is created and absolutely nothing is done with the information. You, therefore, cannot compare the values to each other since they have not been initialized.
Other considerations
When you make a class, in object oriented programming you should think in an OO sort of way.
The player class can/should have a String name; variable and you can then create a Player object and pass the name, exactly like you did. The difference is in your constructor:
//Setting up values
String name;
String suit;
String value;
public player(String name, String suit, String value) {
this.name = name;
this.suit = suit;
this.value = value;
}
This technique creates a player1 object with a name, a suit and a value. Now the values within this object can be compared to equal values in another player object if you so choose.
So I tried to clean up your Player class a bit:
public class Player
{
// The two players are going to enter:
String p1[] = {"Jack", "h", "k"};
String p2[] = {"Jill", "d", "9"};
//Setting up values
String jack = "Jack";
String jill = "Jill";
String h = " Hearts ";
String d = " Diamonds ";
String k = " King ";
int val = 9;
// Score
public int score = 0; // State variable score, set equal to 0
// Player name - Jack, Jill
public Player(String jack, String h, String k)
{
this.jack = jack;
this.h = h;
this.k = k;
}
public String playerName(String player)
{
// not sure what this is doing?
// this first line does nothing at all
// because player gets reassigned to "Jill"
player = "Jack";
player = "Jill";
return player;
}
// Card suit
public String cardSuit(String getcardSuit)
{
return cardSuit;
}
// Card Value for player 1
public String getCardValue()
{
return cardValue;
}
public String getScore(String score)
{
return score;
}
public String player;
public String playerName;
public String cardSuit;
public String cardValue;
public double getScore;
public String getCardSuit()
{
return cardSuit;
}
public int getScore()
{
return 0;
}
}
There are a couple of conventions you should start using. Class names should start with an uppercase letter. Variables and stuff like that should all have lower case letters (unless it is a static).