Setting up the compareTo() method in Java - java

Please Note:
I created a post earlier that had this question along with several others, but was told that since I was asking so many questions in the same post, it'd be better to break it up into individual questions. So please do not mark this as a duplicate, yes the instructions are the same and yes the same code is being used, but the question itself is different. Thanks.
I'm working on a program with the following instructions:
Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable interfaces. Assume that all 8 sides of the octagon are of equal size. The area can be computed using the following formula
area = (2 + 4/square root of 2) * side * side
Write a program (driver) to read in a series of values from a file, display the area and perimeter, create a clone and compare the object and its clone (based on the area). In addition, your program should compare the current object (just read in) with the first object read in. The program ends when a negative number is read from the file.
Here is the code I have so far, This is my GeometricObject class:
public abstract class GeometricObject {
public abstract double getArea();
public abstract double getPerimeter();
}
My Octagon class:
public class Octagon extends GeometricObject implements Comparable<Octagon> {
private double side = 1.0;
protected native Object clone() throws CloneNotSupportedException;
private static int numberOfObjects = 0;
public Octagon() {
}
public Octagon(double side) {
this.side = side;
numberOfObjects++;
}
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
public double getArea() {
return (2 + (4 / (Math.sqrt(2))) * side * side);
}
public double getPerimeter() {
return side * 8;
}
public String toString() {
return "Octagon " + numCreated + ": Area: " + getArea() + "\nPerimeter: "
+ getPerimeter() + "\nClone Compare: " + Cloneable + "\nFirst Compare: "
+ comparisson;
}
public int compareTo(Octagon octagon) {
if(getArea() > octagon.getArea())
return 1;
else if(getArea() < octagon.getArea())
return -1;
else
return 0;
}
public interface Cloneable {
}
}
And my Driver or tester class: (this is where I need the most help)
import java.util.*;
import java.io.*;
public class Driver {
public static void main(String[] args) {
int comparisson = compareTo(octagon);
java.io.File file = new java.io.File("prog7.dat");
Scanner fin = new Scanner(file);
while(fin.hasNext()) {
double side = fin.nextDouble();
if(side < 0.0) break;
Octagon first = new Octagon(side);
System.out.println("Octagon 1: " + first);
}
}
}
And here is the file being used to get the input. Each line is one octagon:
5.0
7.5
3.26
0.0
-1.0
I'm having trouble setting up the compareTo() method. I've never used this before and while I've read the documentation and have a general idea of how it works, I'm having trouble figuring out how to implement it to my specific program.
Along these same lines, I know that the compareTo() method returns an integer value of either -1, 0, or 1 based on whether the current object is smaller, larger, or equal to the object it's being compared with. However, as you can see from the example output, rather than displaying this integer value, I"m supposed to display something like "The first is smaller". I'm pretty sure to do this I would need to assign the return value to a variable and then use if statements to determine what should be printed, but I'm having trouble figuring out how and at what point in my code this should be done?

Based on this line of your requirement: In addition, your program should compare the current object (just read in) with the first object read in. Here's some code to do that. Basically this reads Octagons until a negative number is read, and compares each one with the first Octagon read in.
Octagon first = null;
int i = 0;
while(fin.hasNext())
{
double side = fin.nextDouble();
if(side < 0.0)
break;
Octagon oct = new Octagon(side);
System.out.print("Octagon " + i + ": \"" + oct.toString() + "\"");
if (first == null)
first = oct;
else
{
// Here is where we compare the current Octagon to the first one
int comparison = oct.compareTo(first);
if (comparison < 0)
System.out.print(", less than first");
else if (comparison > 0)
System.out.print(", greater than first");
else System.out.print(", equal to first");
}
Octagon first = new Octagon(side);
System.out.println();
}

int compareTo(Object o)
or
int compareTo(String anotherString)
public class Test {
public static void main(String args[]) {
String str1 = "Strings are immutable";
String str2 = "Strings are immutable";
String str3 = "Integers are not immutable";
int result = str1.compareTo( str2 );
System.out.println(result);
result = str2.compareTo( str3 );
System.out.println(result);
result = str3.compareTo( str1 );
System.out.println(result);
}
}
This produces the following result:
0
10
-10
Also you can check -> http://www.javapractices.com/topic/TopicAction.do?Id=10

Related

Create a simple math game using java objects

I am trying to create a Simple math game using Java objects. My goal is to create a question class, which contains a method to show a question with random numbers, a method to check the answer, a question constructure.
How can I generate 10 random questions using these objects? With additions, substraction and multiplication questions. And print the how many correct answers, at the end.
I have created my question class and my first method shows a random question using the variables "a" and "b". and store the answer.
My second method check the answer with the user input and print the result. So far when I run my program it only shows the same question over and over again.
This is my Question class
import java.util.*;
public class Question {
private int a;
private int b;
private String Question;
private int correct;
Random rand = new Random();
Scanner input = new Scanner(System.in);
int count = 0;
Question(int c, int d) {
x = rand.nextInt(20);
y = rand.nextInt(20);
}
public void askQuestion() {
if (a > b) {
System.out.println("What is " + a + " - " + b + " ?\n");
correct = a - b;
} else {
System.out.println("What is " + a + " + " + b + " ?\n");
correct = a + b;
}
}
public void Check() {
int response = Integer.parseInt(input.next());
if (response == correct) {
System.out.printf("yes.\n");
count++;
} else {
System.out.printf("No. It is " + correct + ".\n");
}
}
}
my main method looks like this
public class Main {
public static void main(String[] args) {
Question q1 = new Question(1,2);
for (int i = 1; i < 10; i++) {
q1.askQuestion();
q1.check();
}
}
}
In my output it shows the question with two random numbers but it prints the same question over and over again. EX:
What is 13 - 1 ?
12
That is correct.
What is 13 - 1 ?
12
That is correct.
What is 13 - 1 ?
3
Wrong!. The answer is 12.
What is 13 - 1 ?
Eventually I want my output to look like:
What is 4 + 6?
What is 7 - 3?
Any help to fix this? and make this game more interactive? Appreciate it.
Your problem is due to the fact that you are creating one Question object, that generates two random numbers (13 and 1 in your case). You then go through a loop of asking 10 Questions, but you use the same Question object - so you are using the same random numbers every time. To fix this, do the following changes:
In your Question constructor, get rid of the parameters, you do not need them. Assign to variables a and b:
private Question(){
a = rand.nextInt(20);
b = rand.nextInt(20);
}
So every time you create a Question, you will generate two random numbers which you assign to your variables you declared earlier in the code at the top (in your code, a and b are declared, but not used).
Then in your main, change it to the following:
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
Question q1 = new Question();
q1.askQuestion();
q1.check();
}
System.out.println("Number correct: " + count); //print amount correct, to use this make variable "count" static.
}
The changes are that now you are creating a new Question object every time you go through the loop, and get new random values. Every time it asks a new Question, it will create a new Question object with new random values and overwrite the old ones. It will ask the question 10 times after you give and check the answer, after which the program will output number of correct answers and stop.
Example output for 3 questions:
What is 17 - 15 ?
2
yes.
What is 8 + 11 ?
19
yes.
What is 9 - 0 ?
5
No. It is 9.
Number correct: 2
If you want a way to dynamically ask a question with random numbers and operators, you can create an Operator enum as seen below to handle calculating the result of a left-hand and right-hand value.
Also, the calls to System.out.print should be in the main program as much as possible. Instead, you should return strings from the Question.
All you need to do is pass the two randomly-generated numbers to the Operator enum and ask it to calculate the result.
Exam (main)
package exam;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Exam {
private static int correctCount = 0;
private static List<Question> questions = randomQuestions(10);
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
questions.stream().forEach(question -> ask(question, input));
input.close();
stats();
}
private static void ask(Question question, Scanner input) {
System.out.print(question.askQuestion());
double guess = input.nextDouble();
boolean isCorrect = question.makeGuess(guess);
System.out.println(question.explain(isCorrect));
System.out.println();
correctCount += isCorrect ? 1 : 0;
}
private static void stats() {
double percentage = (correctCount * 1.0d) / questions.size() * 100;
System.out.printf("Correct: %.2f%% (%d/%d)%n", percentage, correctCount, questions.size());
}
private static List<Question> randomQuestions(int count) {
List<Question> questions = new ArrayList<Question>();
while (count --> 0) questions.add(new Question());
return questions;
}
}
Question (class)
package exam;
import java.util.Random;
public class Question {
private static final Random RAND = new Random(System.currentTimeMillis());
private double left;
private double right;
private Operator operator;
public Question(double left, double right, Operator operator) {
this.left = left;
this.right = right;
this.operator = operator;
}
public Question(int max) {
this(randInt(max), randInt(max), Operator.randomOperator());
}
public Question() {
this(10); // Random 0 -> 10
}
public String askQuestion() {
return String.format("What is %s? ", operator.expression(left, right));
}
public String explain(boolean correct) {
return correct ? "Correct" : String.format("Incorrect, it is: %.2f", calculate());
}
public boolean makeGuess(double guess) {
return compareDouble(guess, calculate(), 0.01);
}
private double calculate() {
return operator.calculate(left, right);
}
#Override
public String toString() {
return String.format("%s = %.2f", operator.expression(left, right), calculate());
}
private static boolean compareDouble(double expected, double actual, double threshold) {
return Math.abs(expected - actual) < threshold;
}
private static double randInt(int range) {
return Math.floor(RAND.nextDouble() * range);
}
}
Operator (enum)
package exam;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public enum Operator {
ADD("+", (left, right) -> left + right),
SUB("-", (left, right) -> left - right),
MUL("*", (left, right) -> left * right),
DIV("/", (left, right) -> left / right);
private static final Random RAND = new Random(System.currentTimeMillis());
private static final List<Operator> VALUES = Collections.unmodifiableList(Arrays.asList(values()));
private static final int SIZE = VALUES.size();
public static Operator randomOperator() {
return VALUES.get(RAND.nextInt(SIZE));
}
private String symbol;
private Operation operation;
private Operator(String symbol, Operation operation) {
this.symbol = symbol;
this.operation = operation;
}
public double calculate(double left, double right) {
return operation.calculate(left, right);
}
public String expression(double left, double right) {
return String.format("%.2f %s %.2f", left, symbol, right);
}
#Override
public String toString() {
return symbol;
}
}
Operation (interface)
package exam;
public interface Operation {
double calculate(double left, double right);
}

Add and Multiply Functions in Java return wrong result [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed last month.
I am doing a very basic Complex Numbers class in Java but when I test my add and multiply functions I don't get the results I expect. I don't understand what is wrong or how to fix it.
When I run the program I get the following output:
a+b: ComplexNumber#1540e19d
a*b: ComplexNumber#677327b6
I should get the proper addition and multiplication of two complex numbers (following the rules of complex numbers of course)
Any help would be much appreciated! Thanks in advance.
Here is the code:
public class ComplexNumber {
private double real;
private double imaginary;
public ComplexNumber(double r, double i) {
real = r;
imaginary = i;
}
public double real() {
return real;
}
public double imaginary() {
return imaginary;
}
public ComplexNumber add(ComplexNumber c) {
double newr = real + c.real();
double newi = imaginary + c.imaginary();
return new ComplexNumber(newr, newi);
}
public ComplexNumber multiply(ComplexNumber c) {
double newr = real*c.real() - imaginary*c.imaginary();
double newi = real*c.imaginary() + imaginary*c.real();
return new ComplexNumber(newr, newi);
}
public static void main(String[] args) {
ComplexNumber c1 = new ComplexNumber(1.0, 2.0);
ComplexNumber c2 = new ComplexNumber(-1.0, 0.5);
String c1plusc2 = c1.add(c2).toString();
String c1timesc2 = c1.multiply(c2).toString();
System.out.println("a+b :" + c1plusc2);
System.out.println("a*b :" + c1timesc2);
}
}
You need to override the toString method in the ComplexNumber class:
#Override
public String toString() {
return real + " + i*" + imaginary;
}
Your .add() & .multiply() methods return a ComplexNumber object. By default,
System.out.println("a*b :" + c1.multiply(c2));
evaluates to
System.out.println("a*b :" + c1.multiply(c2).toString());
The toString() method is inherited from the Object class (since all classes inherit from Object). And since you're not overriding it in the ComplexNumber class, you get the default return value from Object's toString() method:
ClassName#hashCodeOfTheObject
EDIT:
toString() returns a String. Change
ComplexNumber c1plusc2 = c1.add(c2).toString();
ComplexNumber c1timesc2 = c1.multiply(c2).toString();
to
String c1plusc2 = c1.add(c2).toString();
String c1timesc2 = c1.multiply(c2).toString();
Output:
a+b :0.0 + i*2.5
a*b :-2.0 + i*-1.5

adding parts of a javabean together

How do I take the return values of some methods that I wrote in a bean and add them together for an return? For instance:
public double getPart1Average() {
String[] average = new String[]{Part01, Part02, Part03};
int sum = 0;
for (String input : average) {
sum += Integer.parseInt(input);
}
return ((sum * (10) / (3)) * .25);
}
If I have six methods like mostly like this and I need to write a method to return a sum of these methods how would I go about doing this?
Thanks!
If I understood your question then I you just need this:
public static void main(String[] args) {
System.out.println("Sum Of Average:: " + new Average().getSumOfAverage());
}
private double getSumOfAverage() {
return getPart1Average() + getPart2Average() + getPart3Average(); // call all required method here
}
Let me know if this is not what you want.

Implementing the Cloneable Interface

Please Note:
I created a post earlier that had this question along with several others, but was told that since I was asking so many questions in the same post, it'd be better to break it up into individual questions. So please do not mark this as a duplicate, yes the instructions are the same and yes the same code is being used, but the question itself is different. Thanks.
I'm working on a program with the following instructions:
Write a class named Octagon that extends GeometricObject and implements the Comparable and Cloneable interfaces. Assume that all 8 sides of the octagon are of equal size. The area can be computed using the following formula
area = (2 + 4/square root of 2) * side * side
Write a program (driver) to read in a series of values from a file, display the area and perimeter, create a clone and compare the object and its clone (based on the area). In addition, your program should compare the current object (just read in) with the first object read in. The program ends when a negative number is read from the file.
Here is the code I have so far, This is my GeometricObject Class:
public abstract class GeometricObject {
public abstract double getArea();
public abstract double getPerimeter();
}
My Octagon class:
public class Octagon extends GeometricObject implements Comparable<Octagon>, Cloneable {
private double side;
public Octagon() {
}
public Octagon(double side) {
this.side = side;
}
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
public double getArea() {
return (2 + (4 / (Math.sqrt(2))) * side * side);
}
public double getPerimeter() {
return side * 8;
}
public String toString() {
return "Area: " + getArea() + "\nPerimeter: "
+ getPerimeter() + "\nClone Compare: " + "\nFirst Compare: ";
}
public int compareTo(Octagon octagon) {
if(getArea() > octagon.getArea())
return 1;
else if(getArea() < octagon.getArea())
return -1;
else
return 0;
}
#Override
public Octagon clone() {
return new Octagon(this.side);
}
}
And my Driver or tester class: (This is where I need the most help):
import java.util.*;
public class Driver {
public static void main(String[] args) throws Exception {
java.io.File file = new java.io.File("prog7.dat");
Scanner fin = new Scanner(file);
Octagon first = null;
int i = 1;
Octagon older;
while(fin.hasNext())
{
double side = fin.nextDouble();
if(side < 0.0)
break;
Octagon oct = new Octagon(side);
System.out.print("Octagon " + i + ": \"" + oct.toString() + "\"");
if (first == null) {
first = oct;
System.out.print("Equal");
}
else {
int comparison = oct.compareTo(first);
if (comparison < 0)
System.out.print("less than first");
else if (comparison > 0)
System.out.print("greater than first");
else
System.out.print("equal");
}
String cloneComparison = "Clone Compare: ";
older = oct;
Octagon clone = oct.clone();
if ( older.getArea() == clone.getArea() ){
cloneComparison = cloneComparison + "Equal";
} else {
cloneComparison = cloneComparison + "Not Equal";
}
//System.out.println(cloneComparison);
i++;
first = new Octagon(side);
System.out.println();
}
fin.close();
}
}
And here is the file being used to get the input. Each line is one octagon:
5.0
7.5
3.26
0.0
-1.0
I'm having a hard time figuring out how I would implement the Cloneable Interface so that when I print out the results, they will say Clone Comparison: Equal (or not equal).
Any input is greatly appreciated.
What I would do is first implement the method Octagon.clone() by creating an Octagon with the same side length
Public Octagon clone(){
return new Octagon(this.side);
}
In Driver have it clone your newly created Octagon and compare the two (older and newer) with something like this:
String cloneComparison = "Clone Comparision: ";
if ( older.getArea() == newer.getArea() ){
cloneComparison = cloneComparison + "Equal";
} else {
cloneComparison = cloneComparison + "Not Equal";
}
System.println(cloneComparison);
Which also returns the correct string depending on the result.

Issue with interfaces in Java

I'm working through an exercise sheet regarding interfaces, generics and abstract classes in Java. No matter what way I seem to code it, the class Exercise1 won't work. The question asked are commented in the code. Any help would be appreciated, I'm not sure if the error is in the Exercise one code or the implementation of the interface in the classes Time and Point.
/*Exercise 2
(a) Write an interface Printable which has a single method put whose intention is to display a string representation of any object whose class implements Printable. Check it by compiling it. */
interface Printable {
public void put(Object o);
}
/*(b) Enhance classes Point and Time from Chapter 2 of the notes to implement Printable. Check them by compiling them. */
class Point implements Printable {
static Scanner sc = new Scanner(System.in);
private double x, y; // coordinates
Point(double x, double y){ // all-args constructor
this.x = x; this.y = y;
}
Point(){}; // no-args constructor (defaults apply)
void get() {
x = sc.nextDouble();
y = sc.nextDouble();
}
public String toString() {
return "(" + x + "," + y + ")";
}
double distance(Point r) { // distance from r
double xdist = x-r.x; double ydist = y-r.y;
return(Math.sqrt(xdist*xdist+ydist*ydist));
}
public void put(Object o) {
if(o==null) return;
Point p = (Point)o;
System.out.println(x + ":" + y);
}
}
class Time implements Order, Printable {
private int hours; // 0..23
private int mins; // 0..59
Time() { }
Time (int hours, int mins) {
this.hours = hours;
this.mins = mins;
}
public boolean lte(Object other) { // Note public
if (other==null) return false;
Time t = (Time) other;
return hours*60+mins<=t.hours*60+t.mins;
}
public void put(Object o) {
if(o==null) return;
Time t = (Time)o;
System.out.printf("%02d:%02d\n", t.hours, t.mins);
}
}
/*(c) Write a static method print which takes an array of objects whose class implements Printable, and prints each element in the array, one element per line. Check it by placing it in an otherwise empty class and compiling it. */
//this is the bit that is giving me grief, I've tried :
public class Exercise1 {
static void print(Printable[] a) {
for(int i = 0; i < a.length ; i++) {
a[i].put(); // put(java.lang.Object) in Printable cannot be applied to () //a[i].put();
}
}
public static void main(String[] args) {
Time[] t = new Time[10];
for(int i = 0; i < t.length; i++) {
t[i] = new Time();
}
print(t);
}
}
public interface Order {
boolean lte (Object obj); // Object for max generality
// is this object less than or equal to obj?
}
You want to print this, not some arbitrary object o.
I think the problem is the interface Printable. It doesn't match the question correctly.
to display a string representation of any object whose class implements Printable
This doesn't mean, that the put() method should have a parameter of type Object.
The object here refers to this, the object which class implements Printable. And the method put() should print out a string representation of this. So in the simplest case you can implement it with the help of toString().
interface Printable {
/**
* Display a string representation of this
*/
void put();
}
class Point implements Printable {
// ...
/**
* returns a string representation of this
*/
public String toString() {
return "(" + x + "," + y + ")";
}
public void put() {
// this is the same as System.out.println(this.toString());
System.out.println(this);
}
}
Then you can call put() for every Printable in your array.
What you want to do is make the interface Printable look something like this:
interface Printable {
public void print(); //The name of the method should be similar to the name of the interface
}
Then your classes will work like this:
public class Time implements Printable {
private int hours, minutes;
public void print() {
System.out.println( hours + ":" + minutes );
}
}
For Exercise 1, you would then call print() for each element of the array.
By the way: There's already an interface similar to Order. It's called Comparable, and it looks like this:
public interface Comparable<T> {
public void compareTo(T other); //Returns -1 if less than, 0 if equal, and 1 if greater than other object.
}
If no parameter T is given, it becomes Object.
you might want your Printable method to be print(Object object), not put.

Categories