I have the problem that I can't take a number from the arraylist and make it into a int or double which I have to do to cacluate the BMI using weight and height. Please have a look!
The assignment is to put in guests' weight, length, and name and sort the ones with a bad length to height ratio out. In the main I create an array with a couple of guests and when I run it says:
"Exception in thread "main" java.lang.NumberFormatException: For input string "name"
and
java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at Diet.putOnDiet(Diet.java:12)
at TestDiet.main(TestDiet.java:7)
The Diet class is as follows:
public class Diet{
public static ArrayList<Guest> putOnDiet(ArrayList <Guest> list){
ArrayList<Guest> namn = new ArrayList<Guest>();
ArrayList<Guest> hej = new ArrayList<Guest>();
for(int i = 0; i<=list.size()/3; i = i+3){
int langd = Integer.parseInt(list.get(i+1).toString()); //I dont know how to make this work
double vikt = Double.parseDouble(list.get(i).toString());
String name = list.get(i+2).toString();
if ((vikt) > 1.08*(0.9*(langd -100))){
namn.add(new Guest(vikt, langd, name));
}
}
return namn;
}
}
And the Guest class:
public class Guest {
private double weight; private double length; private String name;
public Guest(double weight, double length, String name){
this.name = name; this.weight = weight; this.length = length; // Maybe the problem is here. How do you modify the class to make it work?
}
public String getName() {
return name;
}
public double getWeight()
{
return weight;
}
public double getLength() {
return length;
}
public void setName(String name) {
this.name = name;
}
public void setWeight(double weight) {
this.weight = weight;
}
public void setLength(double length)
{ this.length = length;
}
public boolean isSlim() {
if (weight >= 1.08 * 0.9 * (length - 100)) {
return false;
}
else
return true;
}
public String toString() {
return name + "\n" + weight + "\n" + length;
}
}
Are you sure that the you are parsing an integer?
Well number parsing exception is thrown when it can't parse the number. When the string is not a number like "somthing#$%^&". So try replacing this line
int langd = Integer.parseInt(list.get(i+1).toString());
with this
try {
int langd = Integer.parseInt(list.get(i+1).toString());
} catch (NumberFormatException e) {
System.out.println(list.get(i+1).toString() +" : This is not a number");
System.out.println(e.getMessage());
}
EDIT After reading WOUNDEDStevenJones answer I also think you should not be even using toString() or parsing methods. See WOUNDEDStevenJones answer for more details.
It looks like you'll want to change it to
for (int i=0; i<list.size(); i++) {
double langd = list.get(i).getLength();
double vikt = list.get(i).getWeight();
String name = list.get(i).getName();
}
and kind of ignore your getString() method for this purpose
Note: I'm not sure what you're trying to do with your different indexes, but they'll probably all be .get(i)
The method list.get(i) will return an object of type Guest. Guest has methods, getWeight() and getLength().
list.get(i).getWeight()
This would actually give you a double value in return.
And,
Integer.parseInt(list.get(i).getWeight().toString())
This should be able to parse.
Hope this helps.
_san
Related
I was using this code to print out the list of objects and i don't know if it was because i sorted them but it wont print correctly.
Collections.sort(cereal);
for (int i = 0; i<cereal.size(); i++){
System.out.println(cereal.get(i).toString());
}
I used this compare method for it and I'm not sure if it works either.
#Override
public int compareTo(Cereal o) {
return (int) (this.ratings - o.getRatings());
}
Thank you for the feedback.
Here is what is printing:
Unit3_7.Cereal#668bc3d5
Unit3_7.Cereal#3cda1055
Unit3_7.Cereal#7a5d012c
Unit3_7.Cereal#3fb6a447
Unit3_7.Cereal#79b4d0f
Unit3_7.Cereal#6b2fad11
This is a sample by the way and this is the object:
Cereal cereal1 = new Cereal(data[0], data[1],
Integer.parseInt(data[2]),
Integer.parseInt(data[3]),
Integer.parseInt(data[4]),
Integer.parseInt(data[5]),
Double.parseDouble(data[6]),
Double.parseDouble(data[7]),
Integer.parseInt(data[8]),
Integer.parseInt(data[9]),
Integer.parseInt(data[10]),
Integer.parseInt(data[11]),
Double.parseDouble(data[12]),
Double.parseDouble(data[13]),
Double.parseDouble(data[14]));
I'm getting the data from a csv file that I parsed also, I already confirmed it works and also here is the definition
public Cereal(String brandName, String type, int calories, int protein, int fat, int sodium, Double fiber, Double carbohydrates, int sugar, int potassium, int vitamins,int shelf,
Double weight, Double cups, Double ratings) {
this.brandName = brandName;
this.type = type;
this.calories = calories;
this.protein = protein;
this.fat = fat;
this.sodium = sodium;
this.fiber = fiber;
this.carbohydrates = carbohydrates;
this.sugar = sugar;
this.potassium = potassium;
this.vitamins = vitamins;
this.shelf = shelf;
this.weight = weight;
this.cups = cups;
this.ratings = ratings;
}
You need to provide your own implementation of toString(), e.g.
public String toString() {
return "Brand: " + this.brandName + ", type: " + this.type; // etc, etc
}
Object#toString()'s default implementation is used when you don't provide/inherit a different one for your class, which just gives you type and memory location info.
First of all, your comparator looks off, you probably want something like this instead:
#Override
public int compareTo(Cereal o) {
return ratings.compareTo(o.getRatings());
}
Then, make sure your Cereal class has a human-readable toString() implementation, eg.:
#Override
public String toString {
return String.format("Cereal: %s", this.getBrandName());
}
Ultimately you can print all Cereals in the list one by one as per your code, or you can print them out all at once like so:
Collections.sort(cereal);
System.out.println(cereal);
import java.util.*;
class Distance {
private String name;
private int dist;
public Distance(String name, int dist) {
this.name = name;
this.dist = dist;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDist() {
return dist;
}
public void setDist(int dist) {
this.dist = dist;
}
public String toString() {
return "Distance [name=" + name + ", school street=" + dist + "]";
}
}
class DistanceComp {
public static Distance longdistance(Distance[] dim) {
Distance max = dim[0];
for (int i = 1; i < dim.length; i++) {
if (max.getDist() < dim[i].getDist())
max = dim[i];
}
return max;
}
public static Distance shortdistance(Distance[] dim) {
Distance min = dim[0];
for (int i = 1; i < dim.length; i++) {
if (min.getDist() > dim[i].getDist())
min = dim[i];
}
return min;
}
}
public class week03_01 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Distance[] dist = new Distance[3];
System.out.print(">> how many students? : ");
int num = in.nextInt();
for (int i = 0; i < num; i++) {
System.out.print(">> name and distance : ");
dist[i] = new Distance(in.next(), in.nextInt());
}
System.out.println("\na student with the longest commute to school : " + DistanceComp.longdistance(dist));
System.out.println("a student with the shortest commute to school : " + DistanceComp.shortdistance(dist));
System.out.println("school distance difference is " + );
}
}
I also want to print the "shool distance differecnce".
but it doesn't calculate. i think it has String types.
I think calculate only integer types in an array, but i don't know the code.
Or is s there any other way? Ask for advice.
In your DistanceComp class, create a method to subtract two Distances similar like you did for longdistance and shortdistance:
public static int subtractDistance(Distance dist1, Distance dist2) {
int difference = Math.abs(dist1.getDist() - dist2.getDist());
return difference;
}
Then, use that in your System.out:
System.out.println("school distance difference is " + DistanceComp.subtractDistance(DistanceComp.longdistance(dist), DistanceComp.shortdistance(dist)));
Some notes fyi:
Your code currently only works with 3 students.
Instead of using long names, assign them to a shorter-named variable. This helps with code readability.
//Srivet av Jonathan Arnfjell joar6216
public class Dog {
private String name; // name of dog
private int age; // in years
private int weight; // in pounds
private String breed; // breed of dog
private double tailLength; // Length of tail
private double div = 10;
private double smallTail = 3.7;
private double ageDouble;
private double weightDouble;
public Dog(String name, String breed, int age, int weight) {
this.name = name;
this.breed = breed;
this.age = age;
this.weight = weight;
this.ageDouble = age;
this.weightDouble = weight;
this.tailLength = ageDouble * weightDouble / div;
}
public String getName() {
return name;
}
public String getBreed() {
return breed;
}
public int getAge() {
return age;
}
public int getWeight() {
return weight;
}
public double getTailLength() {
if (breed.equalsIgnoreCase("tax") || breed.equalsIgnoreCase("dachshund")) {
return smallTail;
} else {
return tailLength;
}
}
public void setAge(int newAge) {
if (newAge < age) {
System.out.println("ERROR: Age goes up!");
System.exit(0);
} else
age = newAge;
}
public String toString() {
return name + " " + breed + " " + age + " " + weight + " " + getTailLength();
}
public static void main(String args[]) {
Dog d1 = new Dog("Fluffy", "tax", 5, 6);
Dog d2 = new Dog("Fido", "Fakehund", 7, 15);
System.out.println(d2);
System.out.println(d2.getTailLength());
d2.setAge(9);
System.out.println(d2);
System.out.println(d2.getTailLength());
}
}
Just change your setAge() function to this:
public void setAge(int newAge) {
if (newAge < age) {
System.out.println("ERROR: Age goes up!");
System.exit(0);
} else
age = newAge;
this.tailLength = age * weightDouble / div;
}
}
Always try to have 1 source of truth. If the tail length is generated based on other values, then you shouldn't store the value of tail length, the getTailLength() function could calculate the tail length every time it is called.
You could recalculate tail length every time tail length is called, to make sure the tail length is updated before it is used. But if you are calculating it every time it is used, then there doesn't seem to be a point in storing it.
Another option could be to use something similar to a simplified observer pattern. When weight or age is updated, call a method that updates the tail length.
To me though it makes the most sense not to store it, and to simply calculate it when you want it.
I have a file Inventory.txt that I am trying to print to the screen. Each line from the file goes into an object array. My code compiles with no errors but when I run it, nothing prints nothing to the screen. Im using Mac and TextEdit/Terminal.
import java.util.Scanner;
import java.io.*;
public class VendingMachineSimulator
{
to be imported
public static void main(String[] args) throws FileNotFoundException
{
File InventoryFile = new File("Inventory.txt");
Scanner input = new Scanner(InventoryFile);
//This code block will count the number of lines(products) are in the text file
int counter = 0;
while (input.hasNextLine())
{
counter = counter + 1;
}
Inventory[] InventoryObject = new Inventory[counter];
String line = "";
for (int i = 0; i < counter; i++)
{
String[] ProductArray = line.split("-");
InventoryObject[i] = new Inventory(Integer.valueOf(ProductArray[0]), ProductArray[1], ProductArray[2],
ProductArray[3],Double.valueOf(ProductArray[4]), ProductArray[5],
Integer.valueOf(ProductArray[6]));
}
for (int i = 0; i < counter; i++)
{
System.out.println();
InventoryObject[i].PrintInventory();
}
}
public static void PrintMenu()
{
System.out.println();
System.out.println("Display Inventory: <1>");
System.out.println("Display Currency: <2>");
System.out.println("Purchase Item: <3>");
System.out.println("Exit: <4>");
System.out.println();
}
}
class Inventory
{
private int ID;
private String Type;
private String Name;
private String PriceText;
private double Cost;
private String QuantityText;
private int StockAmount;
//Constructor method. values passed to it from the main method.
public Inventory(int ID, String Type, String Name, String PriceText, double Cost, String QuantityText, int StockAmount)
{
this.ID = ID;
this.Type = Type;
this.Name = Name;
this.PriceText = PriceText;
this.Cost = Cost;
this.QuantityText = QuantityText;
this.StockAmount = StockAmount;
}
public void setID(int ID)
{
this.ID = ID;
}
public void setType(String Type)
{
this.Type = Type;
}
public void setName(String Name)
{
this.Name = Name;
}
public void setPriceText(String PriceText)
{
this.PriceText = PriceText;
}
public void setCost(double Cost)
{
this.Cost = Cost;
}
public void setQuantityText(String QuantityText)
{
this.QuantityText = QuantityText;
}
public void setStockAmount(int StockAmount)
{
this.StockAmount = StockAmount;
}
public int getID()
{
return ID;
}
public String getType()
{
return Type;
}
public String getName()
{
return Name;
}
public String getPriceText()
{
return PriceText;
}
public double getCost()
{
return Cost;
}
public String getQuantityText()
{
return QuantityText;
}
public int getStockAmount()
{
return StockAmount;
}
public void PrintInventory()
{
System.out.println(ID + " " + Type + " " + Name + " " + PriceText
+ " " + Cost + " " + QuantityText + " " + StockAmount);
}
}
You never read a line, you only count them:
while (input.hasNextLine())
{
counter = counter + 1;
}
You have to place line = input.readLine(); inside this loop somewhere and change your logic accordingly, otherwise, it will always stay in the while loop. Think about when you would need to update or read the counter.
This is an endless loop. If there is text in the file, the input has a next line.
Since that line isn't read in the loop, input.hasNextLine() is always true.
while (input.hasNextLine())
{
counter = counter + 1;
}
You should rather use a List to read the Objects, that way you don't need to know the size initially.
You can remove the first while loop as its infinite loop.
Change the for loop to a while loop and do itererate as long as you have a next line and within the loop read the nextline and assign to line string and change the inventoryObject to an ArrayList and add items.
This should ideally resolve the issue.
You are blocking the input from the Inventory.txt file in you while loop. You are only checking if a next line exists without actually reading the next line. So you're going to an infinite loop here:
int counter = 0;
while (input.hasNextLine())
{
counter = counter + 1;
}
You need to call this at some point inside your whilte loop:
input.nextLine();
Tip: You can consolidate all the actions that you are performing inside this while loop. You probably don't need as many loops:
Assigning to line; Declare line before the while loop.
Splitting line into ProductArray. This will be line.split assigned to ProductArray.
Creating the new Inventory object. You may not need an array of Inventory Objects. Simply create one using the ProductArray variable.
Printing the inventory. Simply call the PrintInventory method on the the object created in step 3.
Hope this helps!
I wrote a program that is supposed to read in records from a file and enter them into an array of a Student class. I then need to sort them by name.
import java.io.*;
import java.util.Scanner;
public class StudentTest
{
public static void main(String[] args)
{
String name;
String address;
String major;
double gpa;
int classLevel;
int college;
String blank;
String idNumber;
Scanner fileIn = null;
try
{
fileIn = new Scanner (new FileInputStream("student.dat"));
}
catch (FileNotFoundException e)
{
System.out.println("File not found");
System.exit(0);
}
Student[] aStudent = new Student[15];
int index = 0;
for (index=0; index <= 15; index++)
{
while (fileIn.hasNext())
{
name = fileIn.nextLine();
address = fileIn.nextLine();
major = fileIn.nextLine();
gpa = fileIn.nextDouble();
classLevel = fileIn.nextInt();
college = fileIn.nextInt();
fileIn.nextLine();
idNumber = fileIn.nextLine();
aStudent[index] = new Student(name, address, major, gpa, classLevel, college, idNumber);
aStudent[index].Display();
}
}
Student temp = null;
for (int pass = 0; pass < (index-1); pass++)
{
for (int c = 0; c < (index - 1); c++)
{
if (aStudent[].getName() > aStudent[c+1].getName())
{
temp = aStudent[];
aStudent[]=aStudent[+1];
aStudent[+1]=temp;
}
}
}
}
}
import java.util.Scanner;
public class Student
{
private String name;
private String address;
private String major;
private double gpa;
private int classLevel;
private int college;
private String idNumber;
Scanner keyboard = new Scanner(System.in);
public Student(String name, String address, String major, double gpa, int classLevel, int coll, String idNum)
{
this.name = name;
this.address = address;
this.gpa = gpa;
this.major = major;
this.classLevel = classLevel;
this.college = coll;
this.idNumber = idNum;
}
public String getName()
{
return name;
}
public String getAddress()
{
return address;
}
public String getMajor()
{
return major;
}
public double getGPA()
{
return gpa;
}
public int getClassLevel()
{
return classLevel;
}
public int getCollege()
{
return college;
}
public String getID()
{
return idNumber;
}
public void setAddress(String address)
{
}
public void setMajor(String maj)
{
}
public void setCollege(int coll)
{
}
public void Display()
{
System.out.println("Name: "+getName());
System.out.println("Address: "+getAddress());
System.out.println("Major: " + getMajor());
System.out.println("GPA: "+getGPA()+" Class Level: "+getClassLevel()+" College: "+getCollege());
System.out.println("ID: "+getID());
System.out.println("===============================");
}
}
I wrote the sort the way my proffessor described it in class, but I am still getting errors that "the > operator is undefined for the argument type(s) java.laungage.String"
Any help would be greatly appreciated.
thanks
Edit:
I used Ashan's suggestion and now it looks like this.
for (int pass = 0; pass < (index-1); pass++)
{
for (int c = 0; c < (index - 1); c++)
{
if (aStudent[c].getName().compareTo(aStudent[c+1].getName()) > 0)
{
temp = aStudent[c];
aStudent[c]=aStudent[+1];
aStudent[+1]=temp;
That cleared up that error. However, I am now getting a NullPointerException.
You cannot compare strings using operator such as < , > . To compare strings there is a methodd provided in String class called compareTo. This method compares two strings lexicographically.
compareTo returns
0 incase both the strings are lexicographically equal
-1 if the calling string is lexicographically smaller than the input string
1 if the calling string is lexicographically larger than the input stirng
You can replace the following condition
if (aStudent[].getName() > aStudent[c+1].getName())
using compareTo method as:
if (aStudent[].getName().compareTo(aStudent[c+1].getName()) > 0)
I think error is because you cannot compare how big is the name or how small it is. Making a bubble search to sort names by alphabetical order, you need to check their first characters ASCII. Which is a pretty easy thing to do. I am not good at Java, but C++. So algorithms are same ;) Good luck ;)
You may want to use compareTo() of String. > and < are used for int, float numbers, characters and etc., not for objects like strings. If objects support compare operations, it must implement the Comparable interface, in which you will define the compareTo() method.
This method will return -1 if it is less than the other, 0 if they are equal and 1 if it is greater than the other object.