Whats wrong with this boolean method? - java

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.

Related

HashSet inserts 2 elements which are equal

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();
}

Checking equality of ArrayList's content in Java JUnit

i have a problem with checking equality of two arraylists in JUnit tests. When i test equality of two lists, it only checks if their string representation is the same. It works for simple examples, like [1,2,3],[1,2,3] or when list contains objects that are string-represented with all of their properties. But when i have two lists that have same string representation but some objects have different properties how do i check their equality?
This is the example:
If i have Object of Class Human(int height, int weight, boolean alive), and toString() method is:
public static String toString() {
return this.height + "-" + this.weight;
}
And i have two lists [20-30] and [20-30] but the object in first have
boolean alive = false
and in second
boolean alive = true
how to tell the compiler that lists are not equal? Sorry for confusing explanation and thank you in advance!!! :D
You can use Assert.class
assertArrayEquals(Object[] expecteds, Object[] actuals)
See http://junit.org/junit4/javadoc/4.8/org/junit/Assert.html
The equals-Methode of your Object have to compare all necessary attributes.
The (imho) most readable way to compare lists:
assertThat(actualitems, is(expectedItems));
using assertThat() and the hamcrest is() matcher (see here for further reading).
And in order to make that work: you have to implement equals() (and as consequence hashCode() on your class (see here for how to do that).
In other words: if you want that such fields take part when comparing two objects, than you need to express that by making that "field by field" comparison part of an #Override equals() implementation. Any decent IDE can generate those methods for you - but when learning Java, it is a good exercise to do it yourself a few times.
You need to override the hashcode and equals method. Here is the code
The output is
true
false
public class test {
public static void main(String[] args) {
Human rob = new Human(110, 100, false);
Human bob = new Human(110, 100, true);
Human tob = new Human(110, 100, false);
System.out.println(rob.equals(tob));
System.out.println(rob.equals(bob));
}
}
class Human {
int height;
int weight;
boolean alive;
public Human(int height, int weight, boolean alive) {
super();
this.height = height;
this.weight = weight;
this.alive = alive;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (alive ? 1231 : 1237);
result = prime * result + height;
result = prime * result + weight;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Human other = (Human) obj;
if (alive != other.alive)
return false;
if (height != other.height)
return false;
if (weight != other.weight)
return false;
return true;
}
#Override
public String toString() {
return "Human [height=" + height + ", weight=" + weight + "]";
}
}
A simple way would be
assertTrue("check equality", Arrays.equals(list1.toArray(), list2.toArray());
Only disadvantage is that you only get the information that they aren't equal but not where in the array the inequality happens.

Defining a comparator for a quadratic function object

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;
}

Why doesn't the Vector.indexOf method work for this class?

I have a class exactly like this:
public class Operator {
private String oper;
private boolean ltr;
private int pc;
//Ignore these methods...
public Operator(String t,int prc,boolean as) {oper=t;pc=-prc;ltr=as;}
public int precedence() {return pc;}
public boolean associativity() {return ltr;}
public String getName() {return oper;}
public int hashCode() {
int hash = 3;
hash = 19 * hash + (this.oper != null ? this.oper.hashCode() : 0);
hash = 19 * hash + (this.ltr ? 1 : 0);
hash = 19 * hash + this.pc;
return hash;
}
public boolean equals(Object o){
if (o instanceof String){
return oper.equals(o);
}
return false;
}
public String toString(){
return oper;
}
}
when I do: System.out.println(new Operator("+",4,true).equals("+")); it prints true, which means that equals method is working.
but when I do this:
Vector oprs = new Vector();
oprs.addElement(new Operator("+",4,true));
int iof = oprs.indexOf("+");
System.out.println(iof);
iof is -1. Manual searching finds it well, and System.out.println(oprs.elementAt(0)); prints +. I thought indexOf uses equals method to find the element (like in Java SE) so why on earth oprs.indexOf isn't working?
The type of "+" is String. You can't redefine equality for the String class so your equals method is not reflexive. Check out the Comparator class. It (and the collection classes that use it) might help you.

Is String not considered an 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.

Categories

Resources