Few questions about objects in JAVA - java

I am quite new to programming and my assignment this week is based around objects in java.
Before anything here are my codes
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;
}
}
Then there is this one
public class Zoo {
private 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 = 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() {
return "The zoo is capable of keeping " + park.length + "animals"
+ '\n'
+ "The following is the list of animals currently in the zoo."
+ '\n' + "cage 1 status: " + park[0] + '\n' + "cage 2 status: "
+ park[1] + '\n' + "cage 3 status: " + park[2] + '\n'
+ "cage 4 status: " + park[3] + '\n' + "cage 5 status: "
+ park[4] + '\n' + "cage 6 status: " + park[5] + '\n'
+ "cage 7 status: " + park[6] + '\n' + "cage 8 status: "
+ park[7] + '\n' + "cage 9 status: " + park[8] + '\n'
+ "cage 10 status: " + park[9];
}
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;
}
}
and finally
public class TestZoo {
public static void main(String[] args){
Zoo zoo = new Zoo();
}
}
I have two questions.
First of all as you can see from the toString method in Zoo class, my return statement is way too long. I tried using for loop but i seems i cant really do that in a return statement so I was wondering if there is any simpler way.
The second question is that the exercise tells me to fill up the object zoo that I made in the TestZoo class with names like elephant and spider. I was wondering how i could do this.

1) You can use StringBuilder and loop to build a string. See docs here.
2) You have method addAnimal(Animal first) for adding animal to zoo.

First of all as you can see from the toString method in Zoo class, my return statement is way too long. I tried using for loop but i seems i cant really do that in a return statement so I was wondering if there is any simpler way.
public String toString() {
String str = "The zoo is capable of keeping " + park.length + "animals\nThe following is the list of animals currently in the zoo.";
for(int i = 0; i < park.length; i++)
str += '\n' + "cage " + i + " status: " + park[i];
return str;
}
The second question is that the exercise tells me to fill up the object zoo that I made in the TestZoo class with names like elephant and spider. I was wondering how i could do this.
public class TestZoo {
public static void main(String[] args){
Zoo zoo = new Zoo();
Animal spider = new Animal("spider");
zoo.addAnimal(spider);
}
}
If you've got a lot of animals, the above method won't actually be feasible. So create an array of Strings (Strings because you need one to make an Animal)
String[] arr = {"Spider", "Elephant"};
And then add create an animal for each of the string, and add the animal
for(int i = 0; i < arr.length; i++)
{
Animal a = new Animal( arr[0] );
zoo.addAnimal(a);
}
OR just
for(int i = 0; i < arr.length; i++)
zoo.addAnimal(new Animal(arr[0]));

The toString is like any other method. You can create variables.
String value = "The zoo is capable of keeping " + park.length + "animals";
value =value + '\n'; // etc
return value;
Somthing like
zoo.add(new Animal("zebra"));

For your toString(): Use a StringBuilder with a for-loop in conjuction with String.format() instead to greatly reduce the length.
The loop is important since you're basically echoing the contents of the entire array. Be sure that Animal has overridden toString() to provide valuable information about the instance.
public String toString() {
StringBuilder ret = new StringBuilder("The zoo is capable of keeping " + park.length + "animals");
ret.append("\n");
ret.append("The following is the list of animals currently in the zoo.");
for(int i = 0; i < park.length; i++) {
ret.append(String.format("\ncage %d status : " + park[i].toString()));
}
return ret.toString();
}
To fill your zoo, given the constructor for Animal, I would presume that passing the name "spider" would suffice.
Animal spider = new Animal("spider");
Zoo zoo = new Zoo();
zoo.addAnimal(spider);

Q1: ...return statement is too long...no way to do that in a return statement
A: do it separately. Build the display String (or StringBuilder) in a loop, then return the result.
Q2: ...fill up the object zoo
A: you'll need to create new animals and call addAnimal once for each.
An initialized array of animal names and a for-loop might help:
String names[]= {"aardvark", "bison", "cat", "dog", "eagle", "elephant", "giraffe", "horse", "owl", "emu"};

You can do something like this:
String result = "The list:\n";
for (int i = 0; i< 10; i++) {
result = result + "cage " + i + " status:" + park[i] + "\n";
}
return result;
Here "+" concatenates adjacent strings, and you build up the total result one line at a time.
But using string concatenation is somewhat inefficient (though perfectly adequate for toString in most cases, since that's usually for diagnostics), so many times it's better to use something like StringBuilder, especially for main-line "production" methods.

Related

Need a way to associate strings with individual array elements

I am a complete beginner in programming and I'm working on a program for my mother that tracks her employee's monetary intake through a "horse race", with each employee having a horse and the program tracking their input to a UI made to look like a racetrack. After the help from my last inquiry, I've greatly simplified my mess of code but I am now faced with a new problem in that, after sorting the values largest to smallest, I have no way of associating the sorted values with the correct horse. I understand this explanation is confusing so I hope my code will do most of the talking for me here.
I honestly have no idea where to start with this. As I said in my last inquiry, I'm a complete beginner and severely lack the terminology or knowledge to find an answer here.
public class HorseRace {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String horse1 = "#5 Gitty-Up";
String horse2 = "#7 Lady Simmons";
String horse3 = "#6 Burning Peanutbutter";
String horse4 = "#10 White Lightning";
String horse5 = "#3 Bella";
String horse6 = "#1 Meg The Stallion";
float h1val;
float h2val;
float h3val;
float h4val;
float h5val;
float h6val;
System.out.println("Input amount for " + horse1 + ":");
h1val = sc.nextFloat();
System.out.println("Input amount for " + horse2 + ":");
h2val = sc.nextFloat();
System.out.println("Input amount for " + horse3 + ":");
h3val = sc.nextFloat();
System.out.println("Input amount for " + horse4 + ":");
h4val = sc.nextFloat();
System.out.println("Input amount for " + horse5 + ":");
h5val = sc.nextFloat();
System.out.println("Input amount for " + horse6 + ":");
h6val = sc.nextFloat();
Float[] values = new Float[]{h1val, h2val, h3val, h4val, h5val, h6val};
Arrays.sort(values, Collections.reverseOrder());
//currently displays horses with the wrong number. Need a way to tie the horse name strings to their respective float elements
System.out.println("The current race progress is :");
System.out.println(horse1 + " with $" + values[0]);
System.out.println(horse2 + " with $" + values[1]);
System.out.println(horse3 + " with $" + values[2]);
System.out.println(horse4 + " with $" + values[3]);
System.out.println(horse5 + " with $" + values[4]);
System.out.println(horse6 + " with $" + values[5]);
}
}
my desired result is printing the correct horse with the correct value. For example, if I put that #5 brought in $11 and #7 brought in $14, the program would print that #7 is in the lead with $14 and #5 is in second place with $11.
Currently, the program always prints #5 as being in the lead with the highest value, #7 being in second with the second highest, etc.
I understand this is because I am hard calling the horse1-horse6 values meaning they don't change, but these are acting more as placeholders while I figure out how to associate the right horse with the right value
This is where you should create a Horse class and store the data as instances of Horse.
class Horse {
private String name;
private float value;
public String getName() { return name; }
public float getValue() { return value; }
public void setName(String name) { this.name = name; }
public void setValue(float value) { this.value = value; }
}
And then in your main method:
Horse[] horses = new Horse[6] {
new Horse(), new Horse(), new Horse(), new Horse(), new Horse(), new Horse()
};
horses[0].setName("#5 Gitty-Up");
horses[1].setName("#7 Lady Simmons");
horses[2].setName("#6 Burning Peanutbutter");
// and so on...
// you should use a for loop here instead of writing similar lines over and over again!
for (int i = 0 ; i < 6 ; i++) {
System.out.println("Input amount for " + horses[i].getName() + ":");
horses[i].setValue(sc.nextFloat());
}
Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());
System.out.println("The current race progress is :");
for (int i = 0 ; i < 6 ; i++) {
System.out.println(horses[i].getName() + " with $" + horses[i].getValue());
}
By using a class, you are essentially grouping data that belongs together, together. On the line Arrays.sort(horses, Comparator.comparingDouble(Horse::getValue).reversed());, I am sorting the whole array of horses together, by their values.
If the concepts of classes and objects are new to you, that just means it's time to learn about some new concepts. Classes and objects are very important.
Step 1, create a Horse class. It should have two fields, amount and name. It should implement Comparable because you want to sort it. And looking at your desired output, I would override toString().
class Horse implements Comparable<Horse> {
private String name;
private float amount;
public Horse(String name, float amount) {
this.name = name;
this.amount = amount;
}
#Override
public String toString() {
return String.format("%s with $%.2f", name, amount);
}
#Override
public int compareTo(Horse o) {
return Comparator.comparing((Horse h) -> h.amount)
.thenComparing((Horse h) -> h.name).compare(this, o);
}
}
Step 2, create an array of horseNames and iterate that populating an array of Horses (with amounts). Then sort it, and I would prefer Comparator.reverseOrder() to Collection.reverseOrder() when sorting an array.
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String[] horseNames = { "#5 Gitty-Up", "#7 Lady Simmons",
"#6 Burning Peanutbutter", "#10 White Lightning",
"#3 Bella", "#1 Meg The Stallion" };
Horse[] horses = new Horse[horseNames.length];
for (int i = 0; i < horseNames.length; i++) {
System.out.printf("Input amount for %s:%n", horseNames[i]);
float amt = sc.nextFloat();
horses[i] = new Horse(horseNames[i], amt);
}
Arrays.sort(horses, Comparator.reverseOrder());
System.out.println("The current race progress is :");
for (int i = 0; i < horses.length; i++) {
System.out.println(horses[i]);
}
}

OOP Inheritance homework (Animal to lion super class inheritance) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I need to:
Extend the animal class with a Lion class and have different features(done).
Add a field called Liontype class and add a method classifying the lion type per its weight.(Needs to be derived from the superclass)
And print it out.
There are errors in my code and I've been trying to fix it.
Thank for any assistance in advance.
public class Animal {
private int numTeeth = 0;
private boolean spots = false;
private int weight = 0;
public Animal(int numTeeth, boolean spots, int weight){
this.setNumTeeth(numTeeth);
this.setSpots(spots);
this.setWeight(weight);
}
public int getNumTeeth(){
return numTeeth;
}
public void setNumTeeth(int numTeeth) {
this.numTeeth = numTeeth;
}
public boolean getSpots() {
return spots;
}
public void setSpots(boolean spots) {
this.spots = spots;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
//Extend animal class
public class Lion extends Animal{
public Lion (int numTeeth, boolean spots, int weight){
super(numTeeth, spots, weight);
//Add new attributes
int age = 0;
int cubs = 0;
}
public static void main(String args[]){
//Create lions and assign attributes
Lion lion1 = new Lion();
lion1.numTeeth = 12;
lion1.spots = 1;
lion1. weight = 86;
lion1.age = 7;
lion1.cubs = 3;
//Print attributes
System.out.println("Lion1 attributes:");
System.out.println("Number of teeth : " + numTeeth);
System.out.println("Number of spots : " + spots);
System.out.println("Weight of lion : " + weight + " kgs");
System.out.println("Age : " + age);
System.out.println("No of cubs : " + cubs);
System.out.println(" ");
Lion lion2 = new Lion();
lion2.numTeeth = 16;
lion2.spots = 0;
lion2. weight = 123;
lion2.age = 13;
lion2.cubs = 5;
System.out.println("Lion2 attributes:");
System.out.println("Number of teeth : " + numTeeth);
System.out.println("Number of spots : " + spots);
System.out.println("Weight of lion : " + weight + " kgs");
System.out.println("Age : " + age);
System.out.println("No of cubs : " + cubs);
System.out.println(" ");
}
public class Liontype{
//Trying to get weight from another class
public Integer getWeight()
{
if (weight > 120)
{
System.out.println("This lion is a cub");
}
else if (weight >= 120 && weight < 180)
{
System.out.println("This lion is a female");
}
else if (weight >= 180)
{
System.out.println("This lion is a male");
}
}
}
}
Expected outcome:
Lion attributes:
Number of teeth : 16
Spots : true
Weight of lion : 83kgs
Age : 13
No of cubs : 3
This lion is a female
In addition to errors pointed out by Dmitry, your main in the Lion class has the following:
public static void main(String args[]){
//Create lions and assign attributes
Lion lion1 = new Lion();
lion1.numTeeth = 12;
lion1.spots = 1;
lion1. weight = 86;
lion1.age = 7;
lion1.cubs = 3;
numTeeth spots weight and all the other fields are set private. Your Lion class can't access these fields directly. You are supposed to use your getters and setters you from the Animal
Also when printing attributes in Lion:
//Print attributes
System.out.println("Lion1 attributes:");
System.out.println("Number of teeth : " + numTeeth);
System.out.println("Number of spots : " + spots);
System.out.println("Weight of lion : " + weight + " kgs");
System.out.println("Age : " + age);
System.out.println("No of cubs : " + cubs);
System.out.println(" ");
your fields are attributes to an object. Trying to print the fields directly will give you an compiler error because those are properties of your Lion1 object. You need to use the dot operator like this:
System.out.println("Number of Teeth" + Lion1.getNumTeeth());
Yes, there are many problems in your code that will be obtained at the compilation stage. Perhaps you incorrectly specified your examples. So, please provide details of your problem.
I will point out some that are immediately evident:
You declared local variables
int age = 0;
int cubs = 0;
in the constructor that doesn't actually extend the class Lion with new attributes. Add these attributes as a fields as you did to the class Animal:
private int age = 0;
private int cubs = 0;
and then initialize them in the constructor of the class Lion (if necessary).
In the method public static void main(String args[]), you are trying to use
Lion class fields age, cubs that it does not have. See point 1.
The public Integer getWeight() of the class Liontype has 2 errors. Firstly, the variable weight is not defined, and secondly there is missing the return statement, although the method must return a Integer value.

Java return value dependent on occurence of cats and dogs in a string?

The user enters a string.
The program returns true if cats and dogs occur the same amount of time, else false.
example: catcatdoghotdog = returns TRUE since cat = 2 and dog = 2
// My code
public String three (String str)
{
int cat = 0;
int dog = 0;
for(int a = 0; a < str.length() - 2; a++)
{
if (str.substring(a, a+3).equals("cat"))
{
cat++;
}
if (str.substring(a, a+3).equals("dog"))
{
dog++;
}
}
if(dog == cat)
{
return "TRUE";
}
else
{
return "FALSE";
}
}
System.out.println("Number of times cat and dogs appear in your word: " , + response.three(word)); // doesn't work...
ERROR: + operator is undefined for String argument.
Any Suggestions, really welcome
To concat String and variables, use + is enough.Remove the ,.
System.out.println("Number of times cat and dogs appear in your word: " + response.three(word));
System.out.println("Number of times cat and dogs appear in your word: " + response.three(word));
remove the comma

Java , storing strings into an array

I wish to put the raw questions(rawQuestions) as inputted in this way in command prompt:
java Hangman Hello test 123, into the array (questions). I know rawQuestion will not work down in the "store valid questions into an array" part because of
"error: ';' expected " and "error: not a statement"
in the line
" questions[vCount] = String rawQuestion; "
Therefore how should I rewrite it?
public class Hangman {
//Validation of raw questions
public static boolean isValidQuestion(String rawQuestion){
rawQuestion = rawQuestion.toUpperCase();
boolean vQuestion = true;
for(int i=0; i<rawQuestion.length(); i++){
char c = rawQuestion.charAt(i);
if(!(c>='A' && c<='Z'))
vQuestion = false;
}
return vQuestion;
}
public static void main(String args[]){
boolean vQs[] = new boolean[args.length];
for(int i=0; i<args.length; i++){
String rawQuestion = args[i];
boolean b = isValidQuestion(rawQuestion);
if(b)
System.out.println(rawQuestion + " is a valid question!");
else
System.out.println("Error: " + rawQuestion + ", input must be a word consist of a-z or A-Z");
vQs[i] = b;
}
//count the number of valid questions
int vCount = 0;
for(int i=0; i<vQs.length; i++){
System.out.println(i + " " + vQs[i] );
if(vQs[i])
vCount++;
}
System.out.println("There are " + vCount + " valid questions");
//store valid questions into an array
String questions[] = new String[vCount];
for(vCount=0; vCount<args.length; vCount++){
questions[vCount] = String rawQuestion;
System.out.println( questions[vCount] );
}
}
}
Try this:
String[] validQuestions = Arrays.stream(args)
.filter(Hangman::isValidQuestion)
.toArray(String[]::new);
int validQuestionCount = validQuestions.length;
But even without Streams, your whole method could be done in one for loop, counting and collecting the valid questions in one go instead of having three separate steps:
List<String> validQuestions = new ArrayList<>();
for (int i = 0; i < args.length; i++)
{
String rawQuestion = args[i];
boolean b = isValidQuestion(rawQuestion);
if (b)
{
validQuestions.add(rawQuestion);
System.out.println(rawQuestion + " is a valid question!");
}
else
{
System.out.println("Error: " + rawQuestion + ", input must be a word consist of a-z or A-Z");
}
}
// count the number of valid questions
System.out.println("There are " + validQuestions.size() + " valid questions");
// store valid questions into an array
String questions[] = validQuestions.toArray(new String[validQuestions.size()]);
This way, you do not have to juggle the index variables yourself, which is hard to understand, especially if somebody else tries to read it. (Especially the re-use of vCount is kinda scary to me)
I fixed something and commented, not sure if it works, i haven't compiled it.
public static void main(String args[]){
boolean vQs[] = new boolean[args.length];
int vCount=0;
for(int i=0; i<args.length; i++){
String rawQuestion = args[i];
if(isValidQuestion(rawQuestion)){
System.out.println(rawQuestion + " is a valid question!");
//Here you have enough data to count the valid questions, three loops are not needed.
++vCount;
vQs[i]=true;
}else{
System.out.println("Error: " + rawQuestion + ", input must be a word consist of a-z or A-Z");
vQs[i]=false;
}
}
System.out.println("There are " + vCount + " valid questions");
//store valid questions into an array
String questions[] = new String[vCount];
int j=0;
for(int i=0; i<args.length; i++){
//You need to iterate for all strings, because vQs[] is long args.length
if(vQs[i]){
//Ok the i-th question was valid, let's move it and print it
questions[j] = args[i];
System.out.println( questions[j] );
++j;
}
}
}
}

How to display all scores at the end without a loop?

I am trying to display my score at the end of a questionnaire however my way of doing it only displays the last score.
It would work if I were to put it in a loop, the JOptionPane.showMessageDialog however I only want it to display this once, at the end.
Here is my code.
//Main method
JOptionPane.showMessageDialog(null, printPlayerScore(playerName, playerAge, playerScore, playerCount));
//printPlayerScore method
public static String printPlayerScore(String playerName[], int playerAge[], int playerScore[], int playerCount) {
String displayResult = "";
for(int i = 0; i < playerCount; i++) {
displayResult += "\nName: " + playerName[i] + "\nAge: " + playerAge[i] + "\nScore: " + playerScore[i] + "\n";
}
return displayResult;
}
Example run:
Player1: 12
Player2: 12
When it should be
Player1: 10
Player2: 12
I know I need to change the method to something else, but how else could I do it?
Full code: http://pastebin.com/NME8Dh7N
This is a screaming example of the benefits of Object-Oriented Programming. OOP will make this chunk of code easier to debug, read, and write. I'll write some quick code to explain this better (by no means is it perfect). Notice how we can easily create a nice output string using the properties of a Player. Create an array of Player objects, and pass it into your print method.
public class Player
{
public String name;
public int age;
public int score;
public String toString()
{
return String.format("\nName : %s\nAge: %d\nScore: %s\n", name, age, score);
}
}
public static String printPlayerScore(Player[] players)
{
String displayResult = "";
for(Player player : players)
{
displayResult += player.toString();
}
return displayResult;
}
I personally would not code this problem the way you did as it's not OOP and just very confusing. However, here is something you can use so as to not totally break your code but fix your problem.
The main question you are trying to answer is why is the last score showing up. As others have stated, you are using one array for player scores. Here is hack to change your code to get it working:
List<int[]> playerScoresList = new ArrayList<int[]>();
for (int i = 0; i < playerCount; i++)
{
int playerScore[] = new int[1];
JOptionPane.showMessageDialog(null, "It is " + playerName[i] + "'s turn now!");
checkQuestion(question, questionAnswer, userAnswer);
System.out.println("Name: " + playerName[i] + " || Age: " + playerAge[i] + "\n\n ~~~~ Results ~~~~");
System.out.println(printQuestionnaireResults(question, userAnswer) + " ~~~~ End of Results ~~~~\n");
playerScore = calculatePlayerScore(userAnswer, playerScore, playerCount);
// double playerScorePercentage = ((double)playerScore[i] / (double)question.length) * 100;
double playerScorePercentage = ((double)playerScore[0] / (double)question.length) * 100;
System.out.println(playerName[i] + " got " + playerScore[0] + " questions correct out of " + question.length + "! (" +
playerScorePercentage + "%)\n");
playerScoresList.add(playerScore);
}
JOptionPane.showMessageDialog(null, printPlayerScore(playerName, playerAge, playerScoresList, playerCount));
Other methods that need to be changed:
public static int[] calculatePlayerScore(boolean userAnswer[], int playerScore[], int playerCount) {
for (int i = 0; i < 1; i++) {
playerScore[i] = 0;
for (int ii = 0; ii < userAnswer.length; ii++) {
if (userAnswer[ii]) {
playerScore[i] += 1;
}
}
}
return playerScore;
}
And:
public static String printPlayerScore(String playerName[], int playerAge[], List<int[]> playerScore, int playerCount) {
String displayResult = ""; // Maybe use StringBuilder
for(int i = 0; i < playerCount; i++)
{
int[] score = playerScore.get(i);
displayResult += "\nName: " + playerName[i] + "\nAge: " + playerAge[i] + "\nScore: " + score[0] + "\n";
}
return displayResult;
}
Now, you will create a new array with one element each time for each user.
Please keep in mind this hack is provided such that there should be minimal change in your current code. You should seriously consider re-writing the entire program IMO. I've also commented out some other code as well just to get it working.
According to your pastebin, you only have 1 array for storing question answers. Meaning the n+1 player is overwriting n player's answers.
You could either do a matrix (Array of Arrays), or the easier to read alternative, make a class for players and have that class manage player data, with the program having only a list of players. It will reduce the number of parameters in the function calls and allow for easy individualization of answers.
public class Player {
private String name;
private List<boolean> answers;
private int playerId;
}
The matrix would work like this:
boolean answers[][] = new boolean[playerCount][questionCount];
That way, each player has a separate list of answers that independ from each other.
Then, all you need would be to get send each player as a parameter to the functions and read those as necessary.

Categories

Resources