Implementing the Java comparable interface? [closed] - java

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am not sure how to implement a comparable interface into my complex class. I have the following example code that I am using to try and get my head around it. I know it should be something like public double compareTo (Complex o) and something like that but I am not so sure on how to do it. Any suggestions on how i will implement it?:
import java.util.Scanner;
public class Complex implements Cloneable, Comparable {
private double real;
private double imag;
/*
* public Object clone() throws CloneNotSupportedException { Complex
* objClone = new Complex(); objClone.setReal(this.real);
* objClone.setImag(this.imag); return objClone; }
*/
public Complex(double real, double imag) {
this.real = real;
this.imag = imag;
}
public Complex(double real) {
this.real = real;
}
public Complex() {
}
public void setReal(double real) {
this.real = real;
}
public void setImag(double imag) {
this.imag = imag;
}
public double getReal() {
return real;
}
public double getImag() {
return imag;
}
public void add(Complex num1, Complex num2) {
this.real = num1.real + num2.real;
this.imag = num1.imag + num2.imag;
}
public Complex subtract(Complex num) {
Complex a = this;
double real = a.real - num.real;
double imag = a.imag - num.imag;
return new Complex(real, imag);
}
public Complex multiply(Complex num) {
Complex a = this;
double real = a.real * num.real - a.imag * num.imag;
double imag = a.real * num.imag + a.imag * num.real;
return new Complex(real, imag);
}
public Complex divide(Complex c1, Complex c2) {
return new Complex((c1.real * c2.real + c1.imag * c2.imag) / (c2.real * c2.real + c2.imag * c2.imag),
(c1.imag * c2.real - c1.real * c2.imag) / (c2.real * c2.real + c2.imag * c2.imag));
}
public double absolute() {
return Math.sqrt(real * real + imag * imag);
}
public String toString() {
return this.real + " + " + this.imag + "i";
}
#Override
public Complex clone() throws CloneNotSupportedException {
super.clone();
return new Complex(real, imag);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter the first set of complex numbers respectively: ");
double a = in.nextDouble();
double b = in.nextDouble();
Complex c1 = new Complex(a, b);
System.out.print("Enter the second set of complex numbers respectively: ");
double c = in.nextDouble();
double d = in.nextDouble();
Complex c2 = new Complex(c, d);
Complex result = new Complex(c, d);
result.add(c1, c2);
System.out.println("(" + a + " + " + b + "i) + (" + c + " + " + d + "i) = " + result.toString());
System.out.println("(" + a + " + " + b + "i) - (" + c + " + " + d + "i) = " + c1.subtract(c2));
System.out.println("(" + a + " + " + b + "i) * (" + c + " + " + d + "i) = " + c1.multiply(c2));
System.out.println("(" + a + " + " + b + "i) / (" + c + " + " + d + "i) = " + result.divide(c1, c2).toString());
System.out.println("|" + a + " + " + b + "i| = " + c1.absolute());
}
public double compareTo(Complex other) {
return this.getReal() - other.getReal();
}
}

First, the compareTo method of Comparator interface returns int, not double. Second, if you want to compare two double values in Comparator, you should never use a - b pattern. Instead, use predefined Double.compare method:
public int compareTo(Complex other) {
return Double.compare(this.getReal(), other.getReal());
}
This method carefully handles all the special values like -0.0 or NaN which are not very easy to handle manually. Note that similar methods exist for other types: Integer.compare, Long.compare and so on. It's preferred to use them.
Of course it should be noted that there's no natural order for complex numbers. Here you just compare the real parts, completely ignoring the imaginary parts.

From a mathematical standpoint, Complex numbers can't be ordered, and as such aren't a good fit for the the Comparable interface. To quote the wikipedia article:
Because complex numbers are naturally thought of as existing on a two-dimensional plane, there is no natural linear ordering on the set of complex numbers.
There is no linear ordering on the complex numbers that is compatible with addition and multiplication. Formally, we say that the complex numbers cannot have the structure of an ordered field. This is because any square in an ordered field is at least 0, but i2 = −1.
Having said that, there's nothing technically stopping you from implementing this interface. E.g., you can decide that you are sorting by the real part first and by the imaginary part second. Note that the contract of the compareTo method requires you to return an int, not a double. Also, you should define your class as extending Comparable<Complex> instead of a raw Comparable, so you don't have to mess around with casting and runtime type checking:
#Override
public int compareTo(Complex other) {
int realCompare = Double.compare(getReal(), other.getReal());
if (realCompare != 0) {
return realCompare;
}
return = Double.compare(getImag(), other.getImag());
}
EDIT:
The improvements in JDK 8's Comparator interface allow for a much more elegant implementation with the same behavior:
public int compareTo(Complex other) {
return Comparator.comparingDouble(Complex::getReal)
.thenComparingDouble(Complex::getImag)
.compare(this, other);
}

A few points worth noting.
As other answers have noted you generally should only implement Comparable if there's a natural ordering for instances of the class. As there's no natural ordering for complex numbers you likely shouldn't implement Comparable.
If you are going to provide a natural ordering then you should implement Comparable<Complex> to denote comparing to other instances of Complex (rather than comparing to other objects).
A better alternative to implementing Comparable is to provide one or more Comparator objects for your class that can be used to provide as many orderings as you want. For example:
public class Complex {
private double real;
private double imaginary;
public static final Comparator<Complex> COMPARE_BY_REAL =
Comparator.comparingDouble(Complex::getReal);
public static final Comparator<Complex> COMPARE_BY_IMAGINARY =
Comparator.comparingDouble(Complex::getImaginary);
public static final Comparator<Complex> COMPARE_BY_MODULUS =
Comparator.comparingDouble(Complex::getModulus);
private double getModulus() {
return Math.sqrt(real * real + imaginary * imaginary);
}
}
Then the user of the class can choose the ordering that makes sense to the use:
Optional<Complex> closestToOrigin = complexList.stream().min(Complex::COMPARE_BY_MODULUS);

Related

temperature conversion with ONLY ONE field [duplicate]

Temperature is measured mainly in three units: in degrees Celsius,
degrees Fahrenheit and in kelvins. It’s easy to convert any of them to
the two others:
Kelvin to Celsius: C = K - 273.15
Celsius to Kelvin: K = C + 273.15
Kelvin to Fahrenheit: F = 9./5*(K - 273.15) + 32
Fahrenheit to Kelvin: K = 5./9*(F - 32) + 273.15
Celsius to Fahrenheit: F = 9./5*C + 32
Fahrenheit to Celsius: C = 5./9*(F - 32)
Write class Temperature with one (and only one!) private field of
type double; objects of the class describe temperature. The class
has one constructor and three methods:
Temperature(double tm, char unit) — constructor taking temperature (as a double) and symbol of the unit used: ’C’ for
Celsius, ’F’ for Fahrenheit and ’K’ for kelvins;
three methods („getters”) returning the temperature represented by an object,but in different units:
public double getInC()
public double getInF()
public double getInK()
I don't really understand how to do this if we don't have an field of type char and we can't get any parameters into functions, how to solve it?
Below is what I have so far. It obviously does not fulfil the requirements yet.
public class Temperature {
private final double tm;
public Temperature(double tm, char unit) {
this.tm = tm;
}
public double getInC(){
}
public double getInF(){
}
public double getInK(){
}
}
Just create a field for the unit as well, then you have all the necessary information to do the conversion:
public class Temperature {
private final double tm;
private final char unit;
public Temperature(double tm, char unit) {
this.tm = tm;
this.unit = unit;
}
public double getInC() {
// TODO: conversion
}
public double getInF() {
// TODO: conversion
}
public double getInK() {
// TODO: conversion
}
#Override
public String toString() {
return tm + "" + unit;
}
}
Btw, what you have here is called a 'Value Object', and the recommendation is to add a toString() method so you can print temparatures if you want to (and later also add equals and hashcode methods to compare instances by value).
Alternative solution if you don't want to add a field: convert the temparature given in the constructor into an internal unit (proposal: in K), and then convert to the requested temperatures from Kelvin.
Here is an example of the 'alternative solution':
public class Temperature {
private double value = 0d;
Temperature(double value, char unit) {
this.value = value;
switch (unit) {
case 'C':
this.value = value;
break;
case 'K':
this.value = value - 273.15;
break;
case 'F':
this.value = 5.0 / 9 * (value - 32);
break;
}
System.out.println("Temperature is " + value + "°" + unit);
}
double getInC() {
return value;
}
double getInF() {
return 9.0 / 5 * value + 32;
}
double getInK() {
return value + 273.15;
}
public static void main(String[] args) {
Temperature test = new Temperature(42, 'C');
System.out.println("\t" + test.getInC() + "°C");
System.out.println("\t" + test.getInK() + "°K");
System.out.println("\t" + test.getInF() + "°F");
test = new Temperature(42, 'K');
System.out.println("\t" + test.getInC() + "°C");
System.out.println("\t" + test.getInK() + "°K");
System.out.println("\t" + test.getInF() + "°F");
test = new Temperature(42, 'F');
System.out.println("\t" + test.getInC() + "°C");
System.out.println("\t" + test.getInK() + "°K");
System.out.println("\t" + test.getInF() + "°F");
}
Hope it helps

Java handling large numbers very strangely [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I've been working on a program for a class that uses mass and diameter to calculate a planet's gravity according to the equation g = (G*m)/0.5d^2. I keep getting one digit values only as opposed a mix of one and two digit values. For example: For earth I got 9.8 m/s^2, but for Jupiter (supposed to be 24.9) I got (2.49). This is what I've written thusfar.
public class PlanetGravity {
public static double fromScientificToDouble(String scientific) {
double output = Double.parseDouble(scientific.substring(0, scientific.indexOf("e")));
output *= Math.pow(10, Integer.parseInt(scientific.substring(scientific.indexOf("e") + 1)));
return output;
}
public static double calculateGravity(double d, String m) {
double output = (fromScientificToDouble("6.67e-11") * fromScientificToDouble(m));
System.out.println(output);
output = output / (Math.pow(0.0005 * d, 2));
System.out.println(output);
output = Double.parseDouble(Double.toString(output).substring(0, Double.toString(output).indexOf(".") + 3));
return output;
}
public static void printPlanet(String name, String diameter, String mass, String g) {
System.out.println(" " + name + "\t\t" + diameter + "\t\t" + mass + "\t" + g);
}
public static void main(String[] args) {
System.out.println(" \t\t\t Planetary Data");
System.out.println(" Planet\t\tDiameter (km)\tMass (kg)\tg (m/s^2)");
System.out.println("-------------------------------------------------------------------");
printPlanet("Mercury", "4880", "3.30e23 ", Double.toString(calculateGravity(4880.0, "3.30e23")));
printPlanet("Venus ", "12103.6", "4.869e24", Double.toString(calculateGravity(12103.6, "4.869e24")));
printPlanet("Earth ", "12756.3", "5.972e24", Double.toString(calculateGravity(12756.3, "5.972e24")));
printPlanet("Mars ", "6794", "6.4219e23", Double.toString(calculateGravity(6794, "6.4219e23")));
printPlanet("Jupiter", "142984", "1.900e27", Double.toString(calculateGravity(142984, "1.900e27")));
printPlanet("Saturn", "120536", "5.68e26 ", Double.toString(calculateGravity(120536, "5.68e26")));
printPlanet("Uranus", "51118", "8.683e25", Double.toString(calculateGravity(51118, "8.683e25")));
printPlanet("Neptune", "49532", "1.0247e26", Double.toString(calculateGravity(49532, "1.0247e26")));
}
}
you can simplify your codes by converting from Double to string directly, also using printf allows you to format your string (for example to 3 decimal places).
public class PlanetGravity {
public static double fromScientificToDouble(String scientific) {
//you can convert "3.30e23" directly
return Double.parseDouble(scientific);
}
public static void printPlanet(String name, String diameter, String mass, double g) {
//using printf allows you more control over the formatting like set decimal places and alignment your strings.
System.out.printf("%10s %15s %12s %8.3f \n", name, diameter, mass, g);
// System.out.println(" " + name + "\t\t" + diameter + "\t\t" + mass + "\t" + g); }
public static double calculateGravity(double d, String m) {
double output = (fromScientificToDouble("6.67e-11") * fromScientificToDouble(m));
output = output / (Math.pow(500 * d, 2));
return output;
}
public static void main(String[] args) {
System.out.println(" \t\t\t Planetary Data");
System.out.println(" Planet\t\tDiameter (km)\tMass (kg)\tg (m/s^2)");
System.out.println("-------------------------------------------------------------------");
printPlanet("Mercury", "4880", "3.30e23", calculateGravity(4880.0, "3.30e23"));
printPlanet("Venus", "12103.6", "4.869e24", calculateGravity(12103.6, "4.869e24"));
printPlanet("Earth", "12756.3", "5.972e24", calculateGravity(12756.3, "5.972e24"));
printPlanet("Mars", "6794", "6.4219e23", calculateGravity(6794, "6.4219e23"));
printPlanet("Jupiter", "142984", "1.900e27", calculateGravity(142984, "1.900e27"));
printPlanet("Saturn", "120536", "5.68e26", calculateGravity(120536, "5.68e26"));
printPlanet("Uranus", "51118", "8.683e25", calculateGravity(51118, "8.683e25"));
printPlanet("Neptune", "49532", "1.0247e26", calculateGravity(49532, "1.0247e26"));
}
}
your output will be something along the following

How can I simplify this mathematic operation in my call to super?

I am attempting to do a project which models a grocery store that sells various desserts. Currently, I am trying to create a class for a tiered cake which is derived from a cake class which itself is derived from an abstract dessert class. Essentially, the cake class's constructor has two parameters, name and price. For the tiered cake, the price is the price of the base + the price of the top + an additional 10% of the total. I've found a way to do this, but it's a really long, ugly line of code. I've experimented with a few ways to try and simplify it using variables, but I can't seem to figure out a way that works with the fact that it is being done within a super(). Is there a way I could make it simpler and more efficient? Thanks in advance!
Here is the code:
public class TieredCake extends Cake {
private Cake base;
private Cake top;
public TieredCake (Cake base, Cake top) {
super(base.getName() + " with an upper tier of " + top.getName(), (base.getPrice() + top.getPrice()) * 0.10 + base.getPrice()+top.getPrice());
this.base = base;
this.top = top;
}
public Cake getBase() {
return base;
}
public Cake getTop() {
return top;
}
}
Splitting the call to super onto multiple lines helps a little:
public TieredCake(Cake base, Cake top) {
super(
base.getName() + " with an upper tier of " + top.getName(),
(base.getPrice() + top.getPrice()) * 0.10 + base.getPrice() + top.getPrice()
);
this.base = base;
this.top = top;
}
But more importantly, let’s take a look at that formula. There’s a bit of simplification we can do at a mathematical level:
B := base.getPrice()
T := top.getPrice()
(B + T) * 0.1 + B + T
= (B * 0.1) + (T * 0.1) + B + T
= (B * 1.1) + (T * 1.1)
= (B + T) * 1.1
That gives us:
public TieredCake(Cake base, Cake top) {
super(
base.getName() + " with an upper tier of " + top.getName(),
(base.getPrice() + top.getPrice()) * 1.1
);
this.base = base;
this.top = top;
}

call a method from another class

I'm in an intro programming class, in the lab that I'm currently working on we have to have two classes and pull the methods from one class, "Energy" and have them run in "Energy Driver."
I'm having trouble calling the methods (testOne, testTwo, testThree) over into "EnergyDriver"
public class EnergyDriver
{
public static void main(String [] args)
{
System.out.println(mass1 + " kiolograms, " + velocity1 +
"meters per second: Expected 61250," + " Actual " + kineticE1);
System.out.println(mass2 + " kiolograms, " + velocity2 +
"meters per second: Expected 61250," + " Actual " + kineticE2);
System.out.println(mass3 + " kiolograms, " + velocity3 +
"meters per second: Expected 61250," + " Actual " + kineticE3);
}
}
public class Energy
{
public static void main(String [] args)
{
public double testOne;
{
double mass1;
double velocity1;
double holderValue1;
double kineticE1;
mass1 = 25;
velocity1 = 70;
holderValue1 = Math.pow(velocity1, 2.0);
kineticE1 = .5 *holderValue1 * mass1;
}
public double testTwo;
{
double mass2;
double velocity2;
double holderValue2;
double kineticE2;
mass2 = 76.7;
velocity2 = 43;
holderValue2 = Math.pow(velocity2, 2.0);
kineticE2 = .5 *holderValue2 * mass2;
}
public double testThree;
{
double mass3;
double velocity3;
double holderValue3;
double kineticE3;
mass3 = 5;
velocity3 = 21;
holderValue3 = Math.pow(velocity3, 2.0);
kineticE3 = .5 *holderValue3 * mass3;
}
}
You must have only one main method in any one of class. To call a method from another class you can create an object of that class a call their respective method. Another way is by keeping the calling method to be static so you can access that method via Classname.Methodname.
public class EnergyDriver
{
public static void main(String [] args)
{
Energy energy=new Energy();
System.out.println(mass1 + " kiolograms, " + velocity1 +
"meters per second: Expected 61250," + " Actual " + energy.testOne());
System.out.println(mass2 + " kiolograms, " + velocity2 +
"meters per second: Expected 61250," + " Actual " + energy.testTwo());
System.out.println(mass3 + " kiolograms, " + velocity3 +
"meters per second: Expected 61250," + " Actual " + energy.testThree());
}
}
class Energy
{
public double testOne()
{
double mass1;
double velocity1;
double holderValue1;
double kineticE1;
mass1 = 25;
velocity1 = 70;
holderValue1 = Math.pow(velocity1, 2.0);
kineticE1 = .5 *holderValue1 * mass1;
return kineticE1;
}
public double testTwo()
{
double mass2;
double velocity2;
double holderValue2;
double kineticE2;
mass2 = 76.7;
velocity2 = 43;
holderValue2 = Math.pow(velocity2, 2.0);
kineticE2 = .5 *holderValue2 * mass2;
return kineticE2;
}
public double testThree()
{
double mass3;
double velocity3;
double holderValue3;
double kineticE3;
mass3 = 5;
velocity3 = 21;
holderValue3 = Math.pow(velocity3, 2.0);
kineticE3 = .5 *holderValue3 * mass3;
return kineticE3;
}
}
You can get the value of Kinetic Engergy 1,2,3 by using this code.
You can also use the below code which will use only one method to calculate different values by giving different arguments.
public class EngergyDriver
{
public static void main(String [] args)
{
Energy energy=new Energy();
double mass=25;
double velocity=70;
System.out.println(mass+ " kiolograms, "+velocity+"meters per second: Expected 61250," + " Actual " + energy.testOne(mass,velocity));
}
}
class Energy
{
public double testOne(double mass, double velocity)
{
double mass1;
double velocity1;
double holderValue1;
double kineticE1;
mass1 = 25;
velocity1 = 70;
holderValue1 = Math.pow(velocity1, 2.0);
kineticE1 = .5 *holderValue1 * mass1;
return kineticE1;
}
}
Java programs have SINGLE point of entry and that is through the main method.
Therefore in a single project only one class should have the main method and when compiler will look for that when you run it.
Remember that static methods cannot access non static methods hence main is static therefore it can not access testone two nor three UNLESS you create and object of that type. Meaning in the main method you can have Energy e = new Energy() then access those methods that were not declared with keyword static like e.testone() .
However take note that non static methods can access static methods through Classname.Method name because keyword static entails that only a single copy of that method/variable exists therefore we do not need an object to access it since only one copy exists.
I recommend watching the Java videos from Lynda.com or reading the books Java Head First and Java How To Program (Deitel,Deitel) to give you a boost on your Java knowledge they come with alot of exercises to enhance your knowledge.
Also there are plenty of other questions like this on SO search for them

Quadratic Equation, cannot figure out syntax error

I am working on a school assignment. I am supposed to implement a class and supply the methods getSolution1 and getSolution2. However, I am having 2 issues with my code that I cannot figure out.
Issue #1 is on this line:
solution1= ((-1*b)/> + Math.sqrt(Math.pow(b,2)-(4*a*c)));
The compiler is telling me: Syntax error on token ">", delete this token. I can't figure out if I am doing something wrong on my syntax.
Issue #2 is on the ouput line:
String quadEquation= "The quadratic equation is "+ a + Math.pow(("x"),2) + " + " + b+"x"+ " + " + c+ " =0";
Under the Math.pow I get an error that says: The Method pow is not applicable for the arguments String
Here is my entire code:
public class QuadraticEquation
{
double a;
double b;
double c;
double solution1;
double solution2;
QuadraticEquation (double a, double b, double c){
a= this.a;
b= this.b;
c= this.c;
}
public boolean hasSolution (){
if ((Math.pow(b,2))- (4*a*c)<0){
return false;
}
else
{
return true;
}
}
public double getSolution1 (double a, double b, double c)
{
if (hasSolution){
solution1= ((-1*b) + Math.sqrt(Math.pow(b,2)-(4*a*c))) / 2*a;
return solution1;
}
}
public double getSolution2 (double a, double b, double c){
if (hasSolution){
solution1= ((-1*b) - Math.sqrt(Math.pow(b,2)-(4*a*c))) / 2*a;
return solution2;
}
}
public String toString (double a, double b, double c){
String quadEquation= "The quadratic equation is "+ a + "x^2" + " + " + b+"x"+ " + " + c+ " =0";
return quadEquation;
}
}
Since this is a school assignment, I am looking for guidance on solving this problem.
Thank you.
Your first issue is that you can't use /> together. This is not a proper operation.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/opsummary.html
Second issue is because Math.pow requires two numbers. You have a string in there. It would be like trying to get the power of the word apple. You cant do it. You must first convert that string into an int. How to convert a String to an int in Java?
solution1= ((-1*b) + Math.sqrt(Math.pow(b,2)-(4*a*c))) / 2*a;
There is no such thing as a /> in Java.
String quadEquation= "The quadratic equation is "+ a + "x^2" + " + " + b+"x"+ " + " + c+ " =0";
Math.pow requires numbers whereas you were passing the string "x". the symbol "^" is generally used to say to the power of , therefore x^2 is x to the power of 2. I do not think there is a simple solution to write superscript in standard output.
Java cannot understand what to return if the equation has no solution
public double getSolution2 (double a, double b, double c){
if (hasSolution){
solution1= ((-1*b) - Math.sqrt(Math.pow(b,2)-(4*a*c))) / 2*a;
return solution2;
}
return -1; // or throw an exception.
}
returning -1 will fix it.

Categories

Resources