This is my assignment,
a) Write a quadraticFunction that represents a quadratic ax^2 + bx + c with int coeffients a, b, c. Provide a constructor with 3 int parameters for a, b, c. Provide a method double valueAt(double x) returns the value of this quadratic function at x. Also provide a toString method.
b) override the equals method quadraticmethod class. two quadraticfunction should be considered equal if their respective coeffiecients are equal
c) Make the function objects comparable. The compareTo should first compare 1 if equal compare b if equal compare c
d) Define a comparator class for comparing two QuadraticFunction objects. Provide two constructors: a no-argss constructor and a constructor that takes 1 double parameter. When a comparator is created by the no-args constructor, it should compare two quadraticFunction based on their values at x = 0; when a comparator is created by the constructor with a parameter x, it should compare quadraticFunction based on their values at x
Here's my code
I need help with part D, I don't know how to do some of it
public class Ex4
{
int a;
int b;
int c;
public Ex4(int x, int y, int z)
{
a = x; b=y; c=z;
}
public String toString()
{
String X="";
X= X+a+"x^2"+b+"x"+ "+" + c;
return X;
}
public double valueAt(double x)
{
return (a*x*x+b*x+c);
}
//////// Part B
public boolean equals( Ex4 qf )
{
return(this.a==qf.a && this.b==qf.b && this.c==qf.c);
}
/////Part c
// public int compareTo(Ex4 other)
// {
// if (a.equals(other.a))
// {
// if (b.equals(other.b))
// return c.compareTo(other.c);
// return b.comapreTo(other.b);
// }
// return a.compareTo(other.a);
// }
public int compareTo(Ex4 other)
{
if (a > other.a)
return 1;
else if (a < other.a)
return -1;
else if (b > other.b)
return 1;
else if (b < other.b)
return -1;
else if (c > other.c)
return 1;
else if (c < other.c)
return -1;
else
return 0;
}
////Part d
public static void main(String[] args)
{
System.out.println(new Ex3(1, -5, 6));
}
}
Also in the uncomment the area of code under part c, it says int cannot be dereferenced on line 29, 31, 32,33, and 35
Thanks for the help
You can't call methods on primitives, plain and simple.
A better option is to use Integer's static method, Integer.compare(int a, int b) to compare two ints.
First, writing a custom Comparator isn't too terribly difficult; you need to understand the basic structure of one.
Here's the idea: it reads kind of like you're writing a Comparable entity.
class CustomComparator implements Comparator<Ex4> {
#Override
public int compare(Ex4 left, Ex4 right) {
// Compare the entities as specified by the assignment
}
}
Then, you need to accept that as a constructor argument. That, I leave as an exercise to the reader.
Now, to the syntax issue: you're treating primitive int as an Integer, which does have an equals method on it. Primitives aren't objects, hence they can't be dereferenced. You'll want to use the normal equivalence operators (==, >, <) in this situation. You have this already solved in your second-defined compareTo method.
EDIT: After re-reading your requirements, I'm starting to think that your primitive fields are not the right way to go. You should:
Change your fields from int to Integer
Implement Comparable<Ex4> on your entity class
Rely on the default behavior of compareTo() for Integer; that is, your commented code should "just work" (save for the misspell when comparing against C)
Move the secondary compareTo to its own Comparator entity, as described above.
Try this
import java.util.Comparator;
public class Ex4Comparator implements Comparator<Ex4> {
private double x = 0.0;
public Ex4Comparator() {
}
public Ex4Comparator(double x) {
this.x = x;
}
#Override
public int compare(Ex4 o1, Ex4 o2) {
return Double.compare(o1.valueAt(x), o2.valueAt(x));
}
}
Also your equals method doesn't override Object's equals method. You may want to change it to something like
#Override
public boolean equals(Object o) {
if (o instanceof Ex4) {
Ex4 other = (Ex4)o;
return (a == other.a && b == other.b && c == other.c);
}
return false;
}
Related
I was recently working on a basic task which involved a set and I stumbled upon a curious problem. I have the following class:
public static class Quadruple {
int a;
int b;
int c;
int d;
Map<Integer, Integer> histogram;
public Quadruple(int a, int b, int c, int d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.histogram = new HashMap<>();
histogram.put(a, histogram.get(a) == null ? 1 : histogram.get(a) + 1);
histogram.put(b, histogram.get(b) == null ? 1 : histogram.get(b) + 1);
histogram.put(c, histogram.get(c) == null ? 1 : histogram.get(c) + 1);
histogram.put(d, histogram.get(d) == null ? 1 : histogram.get(d) + 1);
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Quadruple)) {
return false;
}
Quadruple q = (Quadruple) obj;
return q.histogram.equals(this.histogram);
}
#Override
public int hashCode() {
return Objects.hash(a, b, c, d);
}
When I initialize 2 objects of this type like so:
Quadruple q1 = new Quadruple(1, 1, 1, 2);
Quadruple q2 = new Quadruple(1, 1, 2, 1);
q1.equals(q2) returns true but both objects can be added separately to a HashSet.
Now I understand from the contract of HashSet, that if the object you are trying to add equals() an already present object, it should be considered present and nothing should be done.
I've managed to circumvent this issue by using LinkedList and checking if the list contains() the object before adding it, which seems to work accordingly.
My question is, is this behavior normal, as I checked the underlying implementation and saw that the HashMap which is used in HashSet actually checks the values with equals(). Is there something I might be missing?
Your equals method compares histogram, but your hashCode computes the hash from 4 other fields instead. Your implementation of hashCode method violates the contract between equals and hashCode, which says that if two object are equal, they have to have the same hash.
If you look at the implementation of Objects.hash you will get to this code:
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
And as you can see in the loop, the order of arguments passed to Object.hash matters.
As for the solution, I can't really see a reason to have fields other than histogram at all. Either way, given the implementation of your equals method, your hashCode method should look like this:
#Override
public int hashCode() {
return histogram.hashCode();
}
This is one of the practice questions of a test:
Write a method which accepts two integer values as input parameters and returns the boolean result true if the sum of the inputs is greater than or equal to 10 (and falseotherwise)
My answer is below but I don't think it looks correct. Can anyone give me a pointer?
public class Bruh{
public static void main (String [] arg){
int a;
int b;
boolean sum = true;
if ( a+b > 10)
System.out.println ("yo");
else{
sum = false;
}
}
}
You only wrote some code in the main method but you did not create one.
In order to do that you need to actually create a method in your Bruh class like:
public static boolean isSumGreaterThan9(int a, int b){
return (a + b) > 9;
}
Than call it from the main method:
public static void main (String [] arg){
int a = 4; // or whatever
int b = 7; // or whatever
System.out.println(isSumGreaterThan9(a, b));
}
You need to put your logic into a method and change your comparison to >= as per the requirement:
public static boolean isSumGreaterThanOrEqualToTen(int a, int b) {
return (a + b) >= 10;
}
Hi I have this method which I created. Its job is to receive an Integer A, which can either be 10 or 30. It is meant to return TRUE if the value is ten, and false otherwise.
public static boolean checkStatus(int a){
if(a.equals(10)){
return true;
}
return false;
}
For some reason I am getting a compilation error in the if(a.equals(10)) condition, which says INT CANNOT BE DEREFERNCED. If I'm not mistaken, isn't the .equals() method the way to go in this circumstance?
Thanks for your help!
Primitives in Java (int, long, float, etc..) don't have member methods, so the call
if (a.equals(10))
will not compile, as you're trying to de-reference a primitive. Instead, you want to use the == operator to compare primitive values:
if (a == 10)
and reserve the use of the equals() method for non-primitive Objects
You can use equals for objects but an int is a primitive type (a), rather than an object.
Hence you need something like:
public static boolean checkStatus (int a) {
if (a == 10)
return true;
return false;
}
or the shorter and more sensible (in this case):
public static boolean checkStatus (int a) {
return (a == 10);
}
(a) The purists will argue this is proof that Java is not really an object-oriented language, but that's because they're raving loonies :-)
You can use
public static boolean checkStatus(int a){
if(a==10){
return true;
}
return false;
}
or
public static boolean checkStatus(Integer a){
if(a.equals(new Integer(10))){
return true;
}
return false;
}
equals() method belongs to Object class of Java and it has to override each and every Object classes like String, Integer and MyObject(implemented class). But int is not a Java Object and there is no equals() method there.
you can just use == with int values and you can simplify your code as bellow.
public static boolean checkStatus(int a){
return a==10;
}
equals is used for non-primitives basically for Objects.
== is used for primitives.
So, you can use it
public static boolean checkStatus (int a) {
if (a == 10)
return true;
return false;
}
Example 1:
For object, if equals method are overridden, then "equals" method will return true.
public class Employee {
int id;
#Override
public boolean equals(Object obj) {
Employee e = (Employee) obj;
return id == e.id;
}
Employee(int id) {
this.id = id;
}
public static void main(String[] args) {
Employee e1 = new Employee(5);
Employee e2 = new Employee(5);
System.out.println("e1.equals(e2) is: " + e1.equals(e2));
System.out.println("(e1 == e2) is: " + (e1 == e2));
}
}
Output:
e1.equals(e2) is: true
(e1 == e2) is: false
Example 2:
For object, if equals method are not overridden, then "equals" method works as "=="
public class Employee {
int id;
Employee(int id) {
this.id = id;
}
public static void main(String[] args) {
Employee e1 = new Employee(5);
Employee e2 = new Employee(5);
System.out.println("e1.equals(e2) is: " + e1.equals(e2));
System.out.println("(e1 == e2) is: " + (e1 == e2));
}
}
Output:
e1.equals(e2) is: false
(e1 == e2) is: false
Here "equals" method works as "==". So, don't forget to override the equals method for object.
int is a primitive in Java and primitives does not have behaviours a.k.a methods.
hence you cannot call .equals on int. So the options here are to use a ==
public static boolean checkStatus(Integer a){
return (a==10);
}
or convert the int to Integer which is a wrapper class
public static boolean checkStatus(Integer a){
return a.equals(10);
}
You can do something like this with Integer Class
Integer x = 5;
Integer y = 10;
Integer z =5;
Short a = 5;
System.out.println(x.equals(y));
System.out.println(x.equals(z));
System.out.println(x.equals(a));
Output:
false
true
false
You can of course wrap the integer up as :
Integer i = new Integer(a);
Then the equals function can be used with 'i', the new Integer object.
What I do not understand is why I am getting an error compiling my code when a String is in fact an object, and the compiler is saying otherwise. I dont know why I keep getting this error message
symbol: method compareTo(Object)
location: variable least of type Object
.\DataSet.java:17: error: cannot find symbol
else if(maximum.compareTo(x) < 0)
here is the code. I'm trying to utilize the class comparable to allow two objects to use the compareTo method. In the tester, I'm just trying to use a basic string object to compare.
public class DataSetTester
{
public static void main(String[] args)
{
DataSet ds = new DataSet();
String man = "dog";
String woman = "cat";
ds.add(man);
ds.add(woman);
System.out.println("Maximum Word: " + ds.getMaximum());
}
}
Class:
public class DataSet implements Comparable
{
private Object maximum;
private Object least;
private int count;
private int answer;
public void add(Object x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
Comparable Interface:
public interface Comparable
{
public int compareTo(Object anObject);
}
Of course String is an Object.
Comparable is generic now. Why do you feel the need to make those references Object if they are type String? Your code is poor; it's not a Java problem.
I don't see why DataSet needs to implement Comparable. You just need to compare incoming Strings as they're added. Do it this way and you'll fare better:
public class DataSet {
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x) {
if(count == 0){
least = x;
maximum = x;
} else if (least.compareTo(x) > 0) {
least = x;
} else if(maximum.compareTo(x) < 0) {
maximum = x;
}
count++;
}
public String getMaximum() { return this.maximum; }
public String getLeast() { return this.least; }
public int getCount() { return this.count; }
}
The problem is that DataSet implements Comparable, but Object doesn't.
Instead of storing Objects, you want to store Comparables. However, if you do get this to compile, you will get into an infinite loop right here:
public int compareTo(Object anObject)
{
// Yeah, never stop loopin'!
return this.compareTo(anObject);
}
It's recommended that in newer code, you use the generic Comparable<T> interface. Your code would then look like this:
public class DataSet implements Comparable<DataSet>
{
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(DataSet anObject)
{
// I don't really know how you want this to work.
// Come up with your own criteria on what makes a DataSet greater or less than
// another one.
count - anObject.count
}
// Good practice to include this if you're doing a compareTo.
#Override
public boolean equals(Object other)
{
return (other instanceof DataSet) && compareTo((DataSet)other) == 0;
}
public String getMaximum()
{
return maximum;
}
public String getLeast()
{
return least;
}
}
Edit - just saw that you're comparing strings. In that case, you don't really need DataSet to implement Comparable. However, if you do need it for something else, what I wrote still stands.
least and maximum are simply Objects, and the Object class doesn't have a compareTo(...) method, simple as that. least and maximum need to be declared Comparable, not Object. And as written, it makes no sense declaring DataSet to implement the Comparable interface since there are no DataSet objects present and certainly none being compared.
java.lang.Object does not have a compareTo() method.
First of all there is an infinite loop in you code:
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
this method is continuously calling itself.
Regarding your compile error: you have declared variable as Object, which obviously does not have a compareTo method.
There is no compareTo() method in Object. I guess you're looking for String.compareTo().
Type checking is done at compile time and not runtime. At compile time, least and maximum are considered to be objects of type Object and not String.
Is it possible to make HashSet work with any Object ?? I tried to make the Object implement
Comparable but it didn't help
import java.util.HashSet;
public class TestHashSet {
public static void main(String[] args) {
class Triple {
int a, b, c;
Triple(int aa, int bb, int cc) {
a = aa;
b = bb;
c = cc;
}
}
HashSet<Triple> H = new HashSet<Triple>();
H.add(new Triple(1, 2, 3));
System.out.println(H.contains(new Triple(1, 2, 3)));//Output is false
}
}
you need to implement equals(Object) and hashCode()
ensure that the hashcodes are equal when the objects are equal
in your example:
class Triple {
int a, b, c;
Triple(int aa, int bb, int cc) {
a = aa;
b = bb;
c = cc;
}
public boolean equals(Object arg){
if(this==arg)return true;
if(arg==null)return false;
if(arg instanceof Triple){
Triple other = (Triple)arg;
return this.a==other.a && this.b==other.b && this.c==other.c;
}
return false;
}
public int hashCode(){
int res=5;
res = res*17 + a;
res = res*17 + b;
res = res*17 + c;
//any other combination is valid as long as it includes only constants, a, b and c
return res;
}
}
For it to work properly you'll need to implement equals() and hashcode() and you'll also need to make sure they're implemented properly, following the contract set out in the Javadoc (it's perfectly possible to implement them not following this contract but you'll get bizarre results with potentially hard to track down bugs!)
See here for a description.
It already does work with any object. I suggest you need to read the Javadoc instead of guessing about the requirements.