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.
Related
I have the following code,
Object testA = new Object();
Object testB = testA;
System.out.println("A:"+testA.hashCode())
System.out.println("B:"+testB.hashCode())
Per the above, I get the same hashcode for the two objects. I understand that testB is assigned testA and so it could have the same hashcode, however there should be a way to uniquely identify the difference in both these objects right?
Please let me know if there is something obvious that am missing!
however there should be a way to uniquely identify the difference in both these objects right?
There is no difference, since there are no two objects. There is just one object referred by two variables.
In theory, two different objects may have the same hashCode. You can tell them apart by using equals or by using ==. If you don't override equals, it behaves as == by default.
The hashCode function has to be compatible with the equals method in the sense that hashCode has to return the same value for 2 objects that are equal. In this case, they are not only "equal" (according to the equals method), but even the same object (which implies that they are equal).
Besides, independently of what the specification demands, it would impossible for the 2 calls to hashCode to return different values because both variables are actually referencing the same object. There is no way to distinguish testA and testB (apart from the variable name, of course).
You create a new object testA but then assign testB to testA, which assigns the same memory space for both of the objects. This is why its returning the same HashCode.
I read javadoc of this JAVA API method, System.identityHashCode(Object x) and not able to understand a typical use case of this method. Classes that need hashCode() are recommended to have overridden hashCode() method of their own so what is the purpose of this method if Object class already has default hashCode()?
Suppose that class C extends class B and class B overrides hashCode and equals.
Now suppose that for class C, you wish to use the default implementation of hashCode and equals as implemented in the Object class. Normally you don't want to do that, but suppose that each instance of the C class should be a unique key in some HashMap.
You can write :
public class C extends B
{
#Override
public int hashCode ()
{
return System.identityHashCode(this);
}
#Override
public boolean equals (Object other)
{
return this == other;
}
}
Similarly, if B override's toString and you want C's toString to have the default implementation of the Object class, you can write in C :
#Override
public String toString()
{
return getClass().getName() + "#" + Integer.toHexString(System.identityHashCode(this));
}
There aren't a lot of use cases. It's primarily useful if for some reason you have a collection of objects, and only care about their object identities. This is really rare. One example is IdentityHashMap (like #Boris says). It would actually be fine to just use hashCode of the objects for such hash map, but using identity hash would theoretically be faster, because it can avoid "collisions" between objects that are logically equal but aren't the same object (it also allows avoiding of badly implemented hash functions, I guess).
There aren't a lot of use case for such collections, either. You can see use cases for IdentityHashMap here: Practical use of IdentityHashMap in Java 6
Just one difference, if the Object given is null this Method gives 0.
Example 1:
obj.hasCode();
This code throws nullPointerException if the obj is null.
Example 2:
System.identityHashCode(obj);
This method return 0 and doesn't throw an exception cause it checks for null. Also it gives the HashCode that the default hashCode method would return even if you overrides it
Did this answer help you?
I have a base class for multiple data object types in Java. I want to create an equals method in the base class, that works directly when inherited.
Equality is determined by the two objects
belonging to subclasses of the base class. This is easily achievable using
if (!(anObject instanceof BaseClass))
return false;
having the same ID. The ID field is defined by the base class so we can here test that.
if (this.id != ((BaseClass) anObject).id)
return false;
belonging to the same class. This is where I have the problem. Two objects may be of different types (and so be in different lists), but have the same ID. I have to be able to distinguish them. How can I do this?
Use
this.getClass() == anotherObject.getClass()
instead of instanceof. This will return true only if the two object belong to the same class (it's safe to check if class objects are equal by reference). And after that you may compare the id.
You should read this article for problems when implementing equals.
To make it short: use this.getClass()==other.getClass() instead of instanceof, because otherwise the equals() relationship will not be transitive (superInstance.equals(subInstance) will be true, but subInstance.equals(superInstance) will be false).
If I understand you question correctly, you need a way to differentiate two objects of same Class with same id. If so, for this you may use toString() which gives unique representation of objects unless they are string objects. Of course, you must not have overridden toString() in your base class.
example:You can use this, only for the third case that you mentioned.
if (this.toString()!= anObject.toString())
return false;
You can do that with Class.isInstance() method. In your base class, do this.
public static boolean isAnInstance(Object obj)
{
return BaseClass.class.isInstance(obj);
}
Then you can check
if (BaseClass.isAnInstance(object))
{
// Class of object is 'BaseClass' or
// it extends the 'BaseClass'
}
Hope this helps.
The best practice to know objects equality is to override hashcode() and equals() if you maitain objects in a collection
you can refer Why do we have to override the equals() method in Java?
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.
I need to compare 2 instances of a class, that has equals method overridden - it returns string that equal concatenation of parameters. But I need be sure that exists only 1 instance. For this I think to check references.
Is it possible in java?
Use == to compare the references. It's enough to make sure if different variables refer to the same instance.
The easy way to ensure that only one instance exists is to use an Enum.
public enum MyEnum {
NameOfSingleton("aPropertyValue");
private String aProperty;
private MyEnum(String aProperty) {
this.aProperty = aProperty
}
public getAProperty() {
return this.aProperty;
}
Using it is just as simple.
MyEnum.NameOfSingleton.getAProperty();
This doesn't really address your equality question, but it addresses your need for a singleton instance of a class.
I'm not entirely sure what you're trying to do, but if you need to ensure that only one instance of something exists then you can use the static keyword to do so. There are multiple ways you could ensure this with static, for instance creating a static variable called count that keeps track of how many instances of the object have been made. Then in the constructor for the object you just increment count. To see if there is more than one instance of the object you just check the count variable and it should tell you.