Is it possible to compare 2 object from 2 different classes.
lets say i have an vector which adds all the objects from class A. i want to compare some string to the elements of the vector.
Example:
if(string.equals(vector.get(i)))
is this possible ?
Yes, you can call equals(). However, any reasonable implementation of SomeClass.equals() would return false if the argument is of a different class (other than perhaps a subclass).
If string is an instance of java.lang.String, this behaviour is specifically guaranteed:
The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
Your objects are at least in the class Object, and thus (at least partly) in the same class.
Equals method of an object can take any other object. However, it would be up to the implementation to not return true when comparing an apple with an orange
If the list's elements have type other than String it will always return false. From the String documentation for method equals:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
This is generally true for the method equals - it will or should return true only in the eventuality that the compared object is of the same class or a subclass of the former.
It's perfectly valid to write something like;
public class MyClass {
public boolean equals(Object o) {
if(o instanceof SomeUnrelatedClass) return true;
return false;
}
}
But it is not advisable, as least I would try to avoid it. It would make handling MyClass objects a little strange, for example putting them into a hash-based collection.
Related
public class Test {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
System.out.print((o1 == o2) + " " + (o1.equals(o2)));
}
}
I read this in a different answer:
The == operator tests whether two variables have the same references (aka pointer to a memory address).
Whereas the equals() method tests whether two variables refer to objects that have the same state (values).
Here, since o1 and o2 reference two different objects, I get why == returns false.
But both the objects are created using the default constructor of the Object class, and therefore have same values. Why does the equals() method return false?
The implementation of equals() supplied by java.lang.Object is defined to return false, unless the references refer to the same object, in which case it returns true.
This is by design (the method mimics the behaviour of ==) and encourages programmers to implement their own version of equals(), if appropriate, for their class. For example, see java.lang.String#equals which compares the contents if another String is passed as an argument.
You have to write your own equals method that overrides the equals method of class Object because that method returns true if this object is the same as the object in the argument and false otherwise.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). (for more information, read Javadoc)
All Java objects inherit from the Object class. The methods of Object, therefore, are available to all Java objects. One of these methods is equals().
The implementation for equals() in class Object, by default, is identical to the == operator.
If a programmer wishes to use equals() to test objects for value equality, he must override equals() and provide his own implementation (that should comply with the general contract for equals(); refer to the Javadoc).
I am currently taking a java class in university. This is my first programming class and I've stumbled on something that I just cannot understand. As i learned, there are two ways of comparing variables. The first is using the ==, !=, <, > , =< , >= signs for PRIMITIVE variables such as int,double,etc. and the second way is to use the .equals() method for reference type. Now here is my question:
When I use the .getClass() method, I can compare two classes with the .equals() method and the == / != method. Since I can use the ==/!= signs, I'd suppose that the .getClass() method which returns the class of an object must return a primitive type. But searching on google the only thing I found out about this method in the java API is that it returns the class of an object. It doesn't tell me the variable type it returns. How exactly does this method work. What does it return? I tried to ask my teacher but she didn't know. Thank you!
You first need to know how == and != compare the two operands. The reason why == and != cannot be used to compare reference types is that they actually compare the memory addresses of the two reference type variables.
So if I have two strings:
String x = "Hello";
String y = x;
Since x and y share the same memory address after the second line is executed, x == y evaluates to true.
The same goes for the getClass() method. The getClass() method returns the class of the object as a Class<T> object. The question is, why this evaluates to true:
x.getClass() == y.getClass()
The answer is simple. Because x and y are both of type String. So calling getClass will return the same instance. This means the two returned the objects share the same memory address.
"But when I compare strings with the same characters with the == operator, it evaluates to false!" you shouted.
This is because the strings are located at different memory addresses. But the classes that getClass will return is always at the same memory address if the class that they represent is the same. This is due to the way ClassLoader works. But I'm not an expert that.
You just need to know that the objects returned by getClass is at the same memory address if the classes they represent are the same.
The comparators == and != compare equality in the way of identity. So how this works for primitives is obvious. However it can also be used to compare objects. However most often this does not work as expected. There are some exceptions:
Strings are stored as literals, therefore if you define two instances of String containing the same value, they use the same literal. Think of this like both instances pointing to the same memory location.
Enums are basically a collection of constants, therefore an enum value is either the same instance or it is not. It cannot be that the enum has the same value but is another instance.
The same is true for Class objects, which is what you get when calling getClass(). A Class object is created by the ClassLoader the first time it is the *.class file is loaded. On subsequent calls the same Class object is used. Therefore Class objects may be compared with == and !=. However beware that if A.class is loaded by two different ClassLoaders, the class objects that you get returned from them are not of the same instance.
getClass() returns an instance (object) of the Class class. Since each Java class has a single instance of the Class class, if two objects belong to the same class, getClass() for those two objects will return the same isntance and therefore you can use == for comparing them, since == when applied to reference types determines if the two references refer to the same instance.
The .getClass method will just return the class of the object. When you declare a new instance of an object, it will be referring to a class. There can only be one class per jvm but multiple object referring to it. So when you get the class of two objects, they might be referring to the same class!
polymorphism is one of the most important feature for java. for example:
//this shows one use of getclass method.
public class Main {
public static void main(String[] args) {
Main m = new Main();
Animal animal = new Animal();
Human human = new Human();
m.dosomething(animal);//print animal
m.dosomething(human);//print human
}
private void dosomething(Animal an){
System.out.println(an.getClass().toString());
}
}
class Human extends Animal{
private void dance(){
}
}
class Animal{
private void eat(){
}
}
EDIT: the question is why cant I use ".contains" (override .equals() in the object) to compare object attributes (a string) instead of comparing the object itself.
Thanks JB:
Turns out I was confusing overriding compareTo() with overriding equals()
EDIT:
QUESTION REDEFINED:
Why cant I override equals to compare strings in my object:
public boolean equals(Object obj){
...
if(obj instanceof String){
String testString = (String) obj;
...
}
...
}
Or even overload for that matter:
public boolean equals(String stringObj){
...
}
I read somewhere that the compiler doesn't use logic to decide this, it uses types. So if I then call myObj.equals(stringOne + "_" + stringTwo) shouldn't this work as it knows a string is being passed?
Thanks,
Steve.
Why this code doesn't make sense:
because Comparable is supposed to respect rules: if a < b is true, then b > a must be true. You can compare an instance of your class with String, but a String can't compare with an instance of your custom class. You're thus breaking the contract of Comparable
because Vector doesn't use compareTo() to check if an element exists or not. It uses equals().
Because you shouldn't alter the nature of a class just to implement a specific use-case consisting in adding instances of this class to a list and check for duplicates. This logic should be outside of the class. You could simply loop through the list and check is an instance with the item and position already exists or not, before creating your custom class instance.
because you shouldn't use Vector for many years (since Java 2 - we're at Java 8). And since it seems the goal is to avoid duplicates, what you should use is a Set.
Do the right thing, and use a HashSet. Make sure CustomClass implements equals() and hashCode() correctly. You could also use a HashMap<CustomClassKey, CustomClass>, where CustomClassKey is a simple class containing the two fields identifying your CustomClass instances.
I want a brief definition about the equals() , "==" and hashCode(). If i run following code means the output will be "true false 2420395 2420395". But i had understand that equals() method compares the string and "==" compares the reference. But in output the hashCcode() method prints the reference number for both strings as same then why the "==" returns "false".
String str = "Name";
String str1 = new String("Name");
if (str.equals(str1))
System.out.println("true");
else
System.out.println("false");
if (str == str1)
System.out.println("true");
else
System.out.println("false");
System.out.println(str.hashCode());
System.out.println(str1.hashCode());
The equals() and hashCode() methods prove to be very important, when objects implementing these two methods are added to collections. If implemented incorrectly it might screwed up your life.
equals() : This method checks if some other object passed to it as an argument is equal the object in which this method is invoked. It is easy to implement the equals() method incorrectly, if you do not understand the contract. Before overriding this method, following “properties” need to keep in mind -
Reflexive: o1.equals(o1) - which means an Object (e.g. o1) should be equal to itself
Symmetric: o1.equals(o2) if and only o2.equals(o1)
Transitive: o1.equals(o2) && o2.equals(o3) implies that o1.equals(o3) as well
Consistent: o1.equals(o2) returns the same as long as o1 and o2 are unmodified
null comparison : !o1.equals(null) - which means that any instantiable object is not equal to null. So if you pass a null as an argument to your object o1, then it should return false.
Hash code value: o1.equals(o2) implies o1.hashCode() == o2.hashCode() . This is very important. If you define a equals() method then you must define a hashCode() method as well. Also it means that if you have two objects that are equal then they must have the same hashCode, however the reverse is not true
From java source code
*
* #param obj the reference object with which to compare.
* #return {#code true} if this object is the same as the obj
* argument; {#code false} otherwise.
* #see #hashCode()
* #see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
hashCode(): This method returns a hashCode() value as an Integer and is supported for the benefit of hashing based java.util.Collection classes like Hashtable, HashMap, HashSet etc. If a class overrides the equals() method, it must implement the hashCode() method as well.Before overriding this method, you need to keep in mind
Whenever hashCode() method is invoked on the same object more than once during an execution of a Java program, this method must consistently return the same result. The integer result need not remain consistent from one execution of the program to the next execution of the same program.
If two objects are equal as per the equals() method, then calling the hashCode() method in each of the two objects must return the same integer result. So, If a field is not used in equals(), then it must not be used in hashCode() method.
If two objects are unequal as per the equals() method, each of the two objects can return either two different integer results or same integer results (i.e. if 2 objects have the same hashCode() result does not mean that they are equal, but if two objects are equal then they must return the same hashCode() result).
As per java source code
As much as is reasonably practical, the hashCode method defined by java.lang.Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer)
hashCode() does not return the object's reference, but a hash of the object, computed in some way. == does not compare objects using the value of hashCode() but, as you correctly say, by the value of the objects' references.
.equals() compares the actual content of the string.
The "==" operator compares if the two objects are the same reference in memory. If you were to do str = str1;, then the double-equals operator would return true because they point to the same reference in memory.
hashCode() returns a hash of the object in an arbitrary manner. The value returned will always be unique as long as the method is not overridden in some way. If .equals() returns true, the hash code should be the same.
You can read the hashCode documentation. In a few words it says that if (obj1.equals(obj2) is true then obj1.hashCode()==obj2.hasCode() must be true to be a valid implementation.
Note that it does not mean that two different objects cannot share the same hash code. Actually, this example is a valid (but awful) implementation of the method:
class MyClass {
public int hashCode() {return 0;}
}
equals() and hashCode() are different methods and hashCode method should not be used to check if two object references are same.
Reason: hashCode just returns int value for an Object, even two different objects can have same hashCode integer. The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal.
equals() checks if the two object references are same. If two objects are equal then their hashCode must be the same, but the reverse is not true.
As other said '==' compares references. But the two methods are just methods doing something which can be overridden.
Every method does something. If you want to know what it exactly does and what is its meaning you need to read the documentation.
You may override those methods in anyway you want. But please note that you must follow JAVA documentation for these two methods. Because they are used by other classes. For example equals() is used while you try find an object in a list and .hashCode() is used in some hashtable classes provided by JAVA class library.
equals() only compare string it's does not check reference of string
but '==' check reference and data both
in 1st case String str = "Name"; only one object is created but in
2nd case Two object is created
String str1 = new String("Name");
then reference are not same of both string that means it returns false
Only interesting, why method hashCode() in java.lang.String is not static?
And in case of null return e.g. -1 ?
Because frequently need do somethihg like:
String s;
.............
if (s==null) {
return 0;}
else {
return s.hashCode();
}
Thanks.
As others have noted hashCode is a method on Object and is non-static because it inherently relies (i.e. belongs to) an object/instance.
Note that Java 7 introduced the Objects class, which has the hashCode(Object) method, which does exactly what you want: return o.hashCode() if o is non-null or 0 otherwise.
This class also has other methods that deal with possibly-null values, such as equals(Object, Object), toString(Object) and a few others.
because if it was static "1".hashCode() and "2".hashCode() would have returned the same value, which is obviously wrong.
It is specific per instance, and influenced by it, therefore it cannot be static.
Because the hash code of a String is a property of that String.
With the same train of thought you could make every method static.
hashCode is used to get the hashCode of an object, in order to know in which bucket of a HashMap this object must be placed. It thus has to be an instance method of the object, and it must be called polymorphically.
null can be used as a key in a HashMap, but it's treated as a special case.
You seem to be using hashCode for a different purpose, so you have to handle is in a specific way.
Its returning hashCode of an Object not an class.