I am having problems with compareTo - java

Well, I need to make a project where I have two interfaces and they are both used in two unrelated classes. I managed to get everything else to work out properly except for the compareTo method. The two classes I have made are Car and Horse. What I am trying to do is compare the milesGoal from Horse to the one in Car and return either a 1, 0, or -1.
However when I try doing this I get the error "double could not be dereferenced"
I have been stuck on this for a while trying to find different ways to approach this part of the code. I tried using compareTo in the tester class instead of making a method but I got the same error and I am required to make it into a method.
This is the Horse Class:
public class Horse implements milesInterface , kilometersInterface{
private double currentMile;
private double currentKilo;
private double milesGoal;
private double kilosGoal;
private String horseBreed;
// CONSTRUCTORS
public Horse(){
currentMile = 0;
currentKilo = 0;
milesGoal = 0;
kilosGoal = 0;
horseBreed = "Unspecified";
}
public Horse(double cm, double ck, double mg, double kg, String hb){
currentMile = cm;
currentKilo = ck;
milesGoal = mg;
kilosGoal = kg;
horseBreed = hb;
}
// MILE METHODS
public double remainingMiles(){ // Finds the remaining miles
return milesGoal-currentMile;
}
public void halfMile(){ // Divides the desired goal halfway (Miles)
milesGoal = milesGoal/2;
}
public void setMileGoal(double newMile){ // Allows you to set a new goal
milesGoal = newMile;
}
public double getMileGoal(){
return milesGoal;
}
// KILOMETER METHODS
public double remainingKilos(){ // Finds the remaining Kilos
return kilosGoal-currentKilo;
}
public void halfKilo(){ // Divides the desire goal halfway (Kilos)
kilosGoal = kilosGoal/2;
}
public void setKiloGoal(){ // Allows you to set a new goal
kilosGoal = milesGoal*1.6;
}
public void setCurrentKilo(){ // Allows you to set the current Kilo
currentKilo = currentMile * 1.6;
}
// UNIQUE METHODS
public double getMilesStatus(){
return currentMile;
}
public double getKilosStatus(){
return currentKilo;
}
public String getHorseBreed(){
return horseBreed;
}
public void convertToKilos(){ // Converts current miles to kilometers
double kilos = currentMile * 1.6;
System.out.println("The current miles to kilometers is: " + kilos + "km.");
}
public void convertToMiles(){ // Converts current kilometers to miles
double miles = currentKilo * .6;
System.out.println("The current kilometers to miles is: " + miles + "m.");
}
public void milesPerHour(double hours){ // Calculates the mph to the goal by a time
double answer = milesGoal / hours;
System.out.println("The mph needed to reach the desination in " + hours + " hours: " + answer);
}
public void kilosPerHour(double hours){ // Calculates the kmph to the goal by a time
double answer = kilosGoal / hours;
System.out.println("The kilometers needed to reach the desination in " + hours + " hours: " + answer);
}
public int compareTo(Object Other){
if(milesGoal > (Horse)milesGoal.Other)
return 1;
if(milesGoal < (Horse)milesGoal.Other)
return 0;
return -1;
}
}
The Car class is pretty much the same as the Horse one and I need to find a way to compare both of their milesGoal to see which one is greater. I tried multiple things but it doesn't seem to work
This is the interface I made:
abstract interface milesInterface{
public double remainingMiles();
public void halfMile();
public void setMileGoal(double newMile);
public int compareTo(Object Other);
}
abstract interface kilometersInterface{
public double remainingKilos();
public void halfKilo();
public void setCurrentKilo();
public int compareTo(Object Other);
}

First, you are writting attribute.object. This is what fails. Other.milesGoal is a better option.
Another problema is with the casting. What you are doing is trying to cast milesGoal.other to Horse (you want to cast milesGoal)
You should use
if (milesGoal > ((Horse) other).milesGoal)
Also, use proper capitalization (variables go in lowercase, clases/interfaces in uppercase) and setters and getters.
Additionally, you probably will want to cast to the interface so you can use the methods with other clases that implement it
if (milesGoal > ((MilesInterface) other).milesGoal)

Firstly, (Horse)milesGoal.Other should be ((Horse) Other).milesGoal.
I would suggest overloading compareTo with one method for comparing to Horses and one method for comparing to Cars. Then your code looks like
public int compareTo(Horse horse){
if(milesGoal > horse.milesGoal)
return 1;
if(milesGoal < horse.milesGoal)
return -1;
return 0;
}
public int compareTo(Car car){
if(milesGoal > car.milesGoal)
return 1;
if(milesGoal < car.milesGoal)
return -1;
return 0;
}

Related

Doing a course on Code HS, errors say "Bad operator types for binary operator" for lines with the public void. Not sure what I'm doing wrong

EXERCISE DIRECTIONS
In this exercise, you must take your Fraction class
from earlier and extend it by adding a few handy methods.
public void add(Fraction other)
public void subtract(Fraction other)
public void multiply(Fraction other)
public int getNumerator();
public int getDenominator();
public void setNumerator(int x);
public void setDenominator(int x);
public String toString();
Use the FractionTester file to test as you go along.
Note that
public void add(Fraction other)
public void subtract(Fraction other)
public void multiply(Fraction other)
are void methods. They do not return anything. These methods should not create a new Fraction and return it.
Instead, these methods should modify the instance variables to be added, subtracted, or multiplied by the Fraction other.
For example, the following code:
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
System.out.println();
System.out.println("BEFORE:");
System.out.println("first: " + first);
System.out.println("second: " + second);
first.multiply(second);
System.out.println("AFTER:");
System.out.println("first: " + first);
System.out.println("second: " + second);
Should print out:
BEFORE:
first: 1 / 2
second: 1 / 3
AFTER:
first: 1 / 6
second: 1 / 3
The Fraction first was modified by being multiplied by the Fraction second. first was affected, second was not. 1/2 became 1/6 because it was multiplied by 1/3.
This is my code:
public class Fraction
{
// Create your instance variables and constructor here
//Instance variables
private int num;
private int den;
//Constructor
public Fraction(int nume, int dene)
{
num = nume;
den = dene;
}
public void add(Fraction other)
{
Fraction a = num/den + other;
}
public void subtract(Fraction other)
{
Fraction b = num/den - other;
}
public void multiply(Fraction other)
{
Fraction c = num/den * other;
}
public String toString()
{
return "";
}
}
You can't multiply an int (e.g. den or num) directly by a Fraction object. You need to dereference the passed fraction argument and then update the den and num components of the calling instance.
This
public void multiply(Fraction other) {
Fraction c = num/den * other;
}
Needs to be replaced with this.
public void multiply(Fraction other) {
num = num * other.num;
den = den * other.den;
}
When you add or subtract, you need to find common denominators.

Java - Printing ArrayList objects in specific format through toString() method

I'm making a solar system model that uses takes different solar systems and sets of planets through the use of classes. I've chosen to use an arraylist to store each object of a planet within the solar system although am now struggling to output the data in a suitable format.
The format i am looking for in the toString() method is 'Planet X has a mass of A Earths, is BAU from its star, and orbits in C years: could be habitable? D'
I have attempted using for loops to print each planet however don't believe this is the correct way as a return will cause the loop to stop. Many thanks
SolarSystem.java
import java.util.ArrayList;
public class SolarSystem {
private String systemName;
private double systemLuminosity;
public SolarSystem(String name, double luminosity) {
this.systemName = name;
this.systemLuminosity = luminosity;
}
ArrayList<Planet> list = new ArrayList<>();
public void addPlanet(String name, double mass, double distance) {
list.add(new Planet(name, mass, distance, systemLuminosity));
}
public void planetProperties() {
}
public String toString() {
System.out.println(list.size());
String results = "+";
for (Planet planet : list) {
results += planet.getName(); //if you implement toString() for Dog then it will be added here
}
return results;
}
}
Planet.java
public class Planet {
private String planetName;
private double planetMass;
private double distanceFromStar;
private double orbitalPeriod;
private String isHabitable;
public Planet(String name, double mass, double distance, double systemLuminosity) {
setName(name);
setMass(mass);
setDistanceFromSun(distance);
setOrbitalPeriod(distance);
setIsHabitable(mass, distance, systemLuminosity);
}
public void setName(String name) {
planetName = name;
}
public String getName() {
return planetName;
}
public void setMass(double mass) {
planetMass = mass;
}
public double getMass() {
return planetMass;
}
public void setDistanceFromSun(double distance) {
distanceFromStar = distance;
}
public double getDistanceFromStar() {
return distanceFromStar;
}
public void setOrbitalPeriod(double distance) {
orbitalPeriod = Math.sqrt(distance*distance*distance);
}
public double getOrbitalPeriod() {
return orbitalPeriod;
}
public void setIsHabitable(double mass, double distance, double luminosity) {
if (mass >= 0.6 && mass <= 7.0) {
if ((distance >= 0.75 * Math.sqrt(luminosity)) && (distance <= 2.0 * Math.sqrt(luminosity))) {
isHabitable = "yes";
} else {
isHabitable = "no";
}
} else {
isHabitable = "no";
}
}
public String getIsHabitable() {
return isHabitable;
}
}
Main.java
public class Main {
public static void main(String[] args) {
//Create our solar system
SolarSystem ourSystem = new SolarSystem("Our System",1.0);
//Add planets in our solar system
ourSystem.addPlanet("Mercury", 0.055, 0.387);
ourSystem.addPlanet("Venus", 0.815, 0.723);
ourSystem.addPlanet("Earth", 1.0, 1.0);
ourSystem.addPlanet("Mars", 0.107, 1.52);
ourSystem.addPlanet("Jupiter", 317.8, 5.20);
ourSystem.addPlanet("Saturn", 95.2, 9.58);
ourSystem.addPlanet("Uranus", 14.5, 19.20);
ourSystem.addPlanet("Neptune", 17.1, 30.05);
System.out.println(ourSystem.toString());
}
}
You need to implement a toString() method inside your Planet class, for example:
class Planet {
private String planetName;
private double planetMass;
private double distanceFromStar;
private double orbitalPeriod;
private String isHabitable;
#Override
public String toString() {
return String.format(
"Planet %s has a mass of %f Earths, is %f from its star, and orbits in %f years: could be habitable? %s%n",
this.planetName, this.planetMass, this.distanceFromStar, this.orbitalPeriod, this.isHabitable);
}
}
Then inside your SolarSystem class you can create a list with something like this, you already have that part almost correct but I've changed getName to toString:
#Override
public String toString() {
StringBuilder buf = new StringBuilder();
for (Planet planet : list) {
buf.append(planet);
}
return buf.toString();
}
If you want to print out a description for the entire solar system (the entire array list of planets), I would suggest to implement the toString() method inside the Planet class. Doing so will allow you to simply iterate over the Planets array list, and just call planet.toString(). Encapsulating the logic for a singular planet inside the Planet class is the way to go.
You have to redefine toString in the Planet class and replace the toString of SolarSystem to use it.
public class Planet {
...
public String toString() {
return "Planet " + planetName + " has a mass of " + planetMass +
" Earths, is BAU from its star, and orbits in " + orbitalPeriod +
" years: could be habitable? " + isHabitable;
}
}
public class SolarSystem {
...
public String toString() {
String results = "";
for (Planet planet : list) {
results += planet.toString() + "\n"; // Use the toString of planet and add a new line
}
return results;
}
}
Note: for performance reasons as commented by oleg it is preferable to use a StringBuilder to concatenate strings. In this situation where you have few items and the problem is not related to the performances you can leave the + operator.
Growing your java knowledge you will find useful functions like String.join:
Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.
That will help you mantaining your code simpler and cleaner replacing this:
public String toString() {
String results = "";
for (Planet planet : list) {
results += planet.toString() + "\n"; // Use the toString of planet and add a new line
}
return results;
}
with
public String toString() {
return String.join("\n", list);
}
but my tip is to start from the basis of java before trying to use more advanced functions. Otherwise you will use them without knowing what happens behind the scenes
To echo other posters, you need to define a custom toString() method in the planet class first. Please see my suggestions below. They are presented as pseudo-code typed on the fly, not actual code (for there might be a few things here and there that might not compile.)
But the pseudo-code should give an idea for a possible solution. Hit me up if you still have questions.
Based on your requirements:
The format i am looking for in the toString() method is 'Planet X has
a mass of A Earths, is BAU from its star, and orbits in C years: could
be habitable? D'
Your Planet.toString method could look as follows (this is pseudo-code, not bound to be compilable, but you get the gist of it.)
public class Planet {
/* your class as it is, with the
* addition of a possible toString
* implementation */
public String toString(){
return String.format(
"Planet: %s, " +
"mass: %f, " +
"distance: %f, " +
"orbital period: %f, " +
"habitable: %b"
this.getName(),
this.getMass(),
this.getDistanceFromStar(),
this.getOrbitalPeriod(),
this.getIsHabitable());
}
}
Then, your SolarSystem class should have an appropriate toString method that loops over the collection of planets in it. Your original toString method had the right idea, I'm just extending the notion.
public class SolarSystem {
/*
Your solar system class plus some changes
...
*/
public String getName(){
return this.systemName;
}
public String getLuminosity(){
return this.systemLuminosity;
}
public int getPlanetCount(){
return this.list.size();
}
public String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append(
String.format("System: %s\nLuminosity: %f\nPlanet Count:%d\n",
this.getName(),
this.getLuminosity(),
this.getPlanetCount()
)
);
for (final Planet planet : list) {
buffer.append('\t')
.append(planet.getString())
.append('\n');
}
return buffer.toString();
}
}
Now, I'm a bit confused with this:
I have attempted using for loops to print each planet however don't
believe this is the correct way as a return will cause the loop to
stop. Many thanks
A return statement will stop a loop if the return is done within the loop.
A return statement done within a function called within the loop will not end the loop.
That is, a return only ends the function that makes the return call, not functions up in the call chain.
Compare this
for(Foo f : fooList){
if(something){
return; // this will stop the loop
}
}
With this
for(Foo f : fooList){
if(something){
callThisFu(); // the return within callThisFu *will not* exit the loop
}
}
Hope this clear this up.

Object won't construct due to int error even tho they're included in the class [duplicate]

This question already has answers here:
Java error: constructor in class cannot be applied to given types
(3 answers)
Closed 4 years ago.
I have a three classes, one to demo and another to extend the first. Everything compiles when in the demo is gives me this error:
EssayDemo.java:11: error: constructor Essay in class Essay cannot be applied to given types;
Essay termPaper = new Essay();
^
required: int,int,int,int
The four ints are Grammar, Spelling, Length, and Content. I set them up but they don't construct an object properly.
This might have been easier if it weren't for the fact that I have to use two classes that I didn't write. Here are the two specific pieces of code. Here's the essayDemo.java:
/**
This program demonstrates a solution to
the Essay Class programming challenge.
*/
public class EssayDemo
{
public static void main(String[] args)
{
// Create an Essay object.
Essay termPaper = new Essay();
// Assign scores to the object.
// Grammer = 25 points, Spelling = 18 points,
// Length = 20 points, and Content = 25 points.
termPaper.setScore(25.0, 18.0, 20.0, 25.0);
// Display the score details.
System.out.println("Term paper:");
System.out.println("Grammar points: " + termPaper.getGrammar());
System.out.println("Spelling points: " + termPaper.getSpelling());
System.out.println("Length points: " + termPaper.getCorrectLength());
System.out.println("Content points: " + termPaper.getContent());
System.out.println("Total points: " + termPaper.getScore());
System.out.println("Grade: " + termPaper.getGrade());
}
}
And here's the gradedActivity.java:
/**
The GradedActivity class stores data about a graded
activity for the Essay Class programming challenge.
*/
public class GradedActivity
{
private double score; // Numeric score
/**
The setScore method sets the score field.
#param s The value to store in score.
*/
public void setScore(double s)
{
score = s;
}
/**
The getScore method returns the score.
#return The value stored in the score field.
*/
public double getScore()
{
return score;
}
/**
The getGrade method returns a letter grade
determined from the score field.
#return The letter grade.
*/
public char getGrade()
{
char letterGrade;
if (score >= 90)
letterGrade = 'A';
else if (score >= 80)
letterGrade = 'B';
else if (score >= 70)
letterGrade = 'C';
else if (score >= 60)
letterGrade = 'D';
else
letterGrade = 'F';
return letterGrade;
}
}
Here's the code I've written to extend it:
public class Essay extends GradedActivity
{
private final int grammarPossible = 30;
private final int spellingPossible = 20;
private final int lengthPossible = 20;
private final int contentPossible = 30;
private final int overallPossible = 100;
private int grammarGrade;
private int spellingGrade;
private int lengthGrade;
private int contentGrade;
private int overallGrade;
public Essay(int grammar, int spelling, int length, int content){
setGrammarGrade(grammar);
setSpellingGrade(spelling);
setLengthGrade(length);
setContentGrade(content);
setOverallGrade();
setScore(getOverallGrade());
}
public int getGrammarGrade(){
return grammarGrade;
}
public void setGrammarGrade(int grammarGrade){
this.grammarGrade = grammarGrade;
}
public int getSpellingGrade(){
return spellingGrade;
}
public void setSpellingGrade(int spellingGrade){
this.spellingGrade = spellingGrade;
}
public int getLengthGrade(){
return lengthGrade;
}
public void setLengthGrade(int lengthGrade){
this.lengthGrade = lengthGrade;
}
public int getContentGrade(){
return contentGrade;
}
public void setContentGrade(int contentGrade){
this.contentGrade = contentGrade;
}
public int getOverallGrade(){
return overallGrade;
}
public void setOverallGrade(){
int grades = grammarGrade + spellingGrade + lengthGrade + contentGrade;
this.overallGrade = grades;
}
public int getGrammarPossible(){
return grammarPossible;
}
public int getSpellingPossible(){
return spellingPossible;
}
public int getLengthPossible(){
return lengthPossible;
}
public int getContentPossible(){
return contentPossible;
}
public int getOverallPossible(){
return overallPossible;
}
}
I have four ints in the essay method but they aren't excepted in the constructor. Everything compiles.
required: int,int,int,int
The error is telling you that your constructor requires arguments (public Essay(int grammar, int spelling, int length, int content)). Right now you are trying to construct an Essay , but are not passing any arguments to it.
You need to provide those arguments, or provide a no args constructor:
public Essay(){}
Or if you wanted to initialize them all to zero and initialize the variables later:
Essay termPaper = new Essay(0,0,0,0);

Modifying Fraction Class and Test Driver JAVA

My Professor has created code that needs to be modified. The only problem is I don't understand his style at all on top of being a fairly new programmer myself. The parameters for the assignment are as follows:
• Modify setters so that they ignore inappropriate values (i.e., divide by zero)
• Implement the equals() method inherited from the top-level Object class
• Implement less than and greater than methods
• Implement add, subtract, and multiply methods
• Makes sure the equals method returns true for any two fractions that are arithmetically equal.
• Make sure that the equals method does not alter the values of the fractions being compared.
• The lessThan and greaterThan methods must each return a Boolean value, not a string.
• The provided reduce method returns a new (reduced) fraction object as its function value
I am completely lost about this assignment as I don't have the slightest clue where to even begin. Any and all help would be greatly appreciated!!!! I have the feeling that once I see it done, it will all make sense to me. I am just not used to this style of teaching at all.
public class Fraction {
private int numer;
private int denom;
public Fraction() { // no-arg constructor
numer = 0;
denom = 1;
}
public Fraction(int numer, int denom) {
this.numer = numer;
this.denom = denom;
}
public Fraction(Fraction frac) { // copy constructor
numer = frac.getNumer();
denom = frac.getDenom();
}
// getters and setters
public int getNumer() {
return numer;
}
public void setNumer(int x) {
numer = x;
}
public int getDenom() {
return denom;
}
public void setDenom(int x) {
denom = x;
}
// Special Methods
public String toString() {
return numer + "/" + denom;
}
// Other Methods
public Fraction reduce() {
Fraction temp = new Fraction();
int GCD = gcd(numer, denom);
temp.setNumer(numer / GCD);
temp.setDenom(denom / GCD);
return temp;
}
// Private Methods
private int gcd(int n1, int n2)
{
int M, N, R;
if (n1 < n2)
{
N = n1;
M = n2;
}
else
{
N = n2;
M = n1;
}
R = M % N;
while (R != 0)
{
M = N;
N = R;
R = M % N;
}
return N;
}
public static void main(String[] args) {
// test constructors
Fraction frac0 = new Fraction();
System.out.println("TESTING NO-ARG CONSTRUCTOR");
System.out.println("frac0: Result should be 0/1:");
System.out.println("Numer = " + frac0.getNumer());
System.out.println("Denom = " + frac0.getDenom());
System.out.println("TESTING int/int CONSTRUCTOR");
Fraction frac1 = new Fraction(2,4);
System.out.println("frac1: Result should be 2/4:");
System.out.println("Numer = " + frac1.getNumer());
System.out.println("Denom = " + frac1.getDenom());
System.out.println("TESTING Fraction CONSTRUCTOR");
Fraction frac2 = new Fraction(frac1);
System.out.println("frac2: Result should be 2/4:");
System.out.println("Numer = " + frac2.getNumer());
System.out.println("Denom = " + frac2.getDenom());
System.out.println("TESTING COPY CONSTRUCTOR frac1  frac2");
if (frac1.getNumer() == frac2.getNumer() &&
frac1.getDenom() == frac2.getDenom() &&
frac1 != frac2)
{
System.out.println("Copy constructor working");
}
else
System.out.println("PROBLEM with copy constructor");
// test equal method
System.out.println("TESTING EQUALITY OF frac1 and frac2 -");
System.out.println("SHOULD BE FOUND EQUAL:");
if (frac1.equals(frac2))
{
System.out.println("frac1 and frac2 found equal");
}
else
{
System.out.println("frac1 and frac2 NOT equal");
}
// test reduce method
System.out.println("TESTING reduce METHOD ON frac1");
Fraction reduced_frac1 = frac1.reduce();
System.out.println("Reduced frac1 = " + reduced_frac1);
// test getters and setters
frac2.setNumer(8);
frac2.setDenom(12);
System.out.println("Numer = " + frac2.getNumer());
System.out.println("Denom = " + frac2.getDenom());
// System.out.println("GCD of 2/4 = " + frac1.gcd(1,4));
}
//* TO BE COMPLETED *
}
There is nothing wrong with his teaching methods and with some further study I am sure you can figure it out. No one here is going to do it for you and I don't want to do your homework so I will ask the common question, what have you tried so far? I've given you one of the modified setters. Keep working, study your java better or you are going to have a hard time when it gets difficult.
//Here is where you start
public void setDenom(int x){
if(x > 0){
denom = x;
}else{
//throw an error
}
}

implementation of simple calculator

Create a program which simulates a very simple calculator
So I have been asked to implement an abstract class that represents binary (having 2 arguments) arithmetic expression
abstract class ArithmeticExpression {
double binary1;
double binary2;
public abstract void evaluate ();
public abstract void display ();
}
so then I created sub classes add, multiply, subtract, and divide. In subtract I have:
public class subtract extends ArithmeticExpression {
// private double result;
double binary1;
double binary2;
public subtract (double x, double y) {
this.binary1 = x;
this.binary2 = y;
}
public void evaluate () {
System.out.println("Expression: " + getsubX() + " - " + getsubY() + " = ");
// return result;
}
public void display () {
}
public double getsubX() {
}
public double getsubY() {
}
Using the classes I should be able to represent any arbitrary expression, with no hard coding.
It is also said evaluate should return the result as double and display method should print the expression out in string. Am I on the right track? What am I missing here? The part I do not understand how it is able to represent any expression?
Using your abstract ArithmeticExpression, here's what the Subtract class should look like. Java classes start with a capital letter.
public class Subtract extends ArithmeticExpression {
double result;
public Subtract(double x, double y) {
this.binary1 = x;
this.binary2 = y;
}
#Override
public void evaluate() {
result = binary1 - binary2;
}
#Override
public void display() {
System.out.println("Expression: " + binary1 +
" - " + binary2 + " = " + result);
}
}
You don't have to re-declare binary1 and binary2. They are instantiated in the abstract ArithmeticExpression class.
You do have to provide a double for the result. This should have been done in the abstract ArithmeticExpression class.
The evaluate() method is for evaluation.
The display() method is for display.
You don't have to define any other methods in your Subtract concrete class.
If you want to evaluate any expession inserted in form of
4 + 3 * ( 4 + 5)
You either need to create binary tree or stack and fill those values and operators in.
What I quite dont understand is your so called binary represented in double. If you want to have binary calc, you should use unsigned int or long (or any other type, that is not floating point)

Categories

Resources