import java.util.HashSet;
import java.util.Set;
class Employee {
#Override
public int hashCode() {
System.out.println("Hash");
return super.hashCode();
}
}
public class Test2 {
public static void main(String[] args) {
Set<Employee>set= new HashSet<>();
Employee employee = new Employee();
set.add(employee);
System.out.println(set);// if we comment this "Hash" will be printed once
}
}
Above code calls hashCode method 2 times if we print set. Why hashcode method is called on System.out.println()?
Find the following reason for printing Hash two times
For finding the hash value when you insert the Employee into the HashSet
When you print the set, it's calls the hashCode() method inside the default toString() method from Object class.
The default toString() method from Object class API docs says
The toString() method for class Object returns a string consisting of
the name of the class of which the object is an instance, the at-sign
character `#', and the unsigned hexadecimal representation of the hash
code of the object. In other words, this method returns a string equal
to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
See this. In short, the default toString() function calls hashCode() and uses a hexadecimal representation of the hash as part of the String.
The first call to hashCode() is executed when adding an Employee to your set variable, as it's needed in order to calculate which bucket to put it in.
The second call is a bit sneaker. Any Collection's default toString() is a coma-delimited concatination of all its elements toString()s enclosed by square brackets (e.g., [object1, object2]). Any object's default toString(), if you don't override it is getClass().getName() + "#" + Integer.toHexString(hashCode()). Here, since you don't override Employee's toString(), it's called again when you print set.
Related
I have written the following code:-
Test ob = new Test();
System.out.println(ob.toString());
System.out.println(ob.hashCode());
and the output is
Test#15db9742
366712642
i understand that the second value is the hashcode of the object and it is an integer value but i am not able to understand what is the first value. If it is the hashcode of the object then how can it be string and not integer
If you read the docs for toString very carefully:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
366712642 in hex is exactly 15DB9742!
If it is the hashcode of the object then how can it be string and not integer?
As you can see from the docs, it is the class name, plus #, plus the dashcode, not just the hash code. Also, the method's name is toString. It would be weird if it returned an int, wouldn't it?
It represents classname#HashCode_in_Hexadeciaml_form. So, the string which you are seeing is actually the hexadecimal form of the integer hashcode
You can look the source code of Object.java. toString method is meant to provide information about class at runtime, so can be overriden. What you're doing is calling the default toString method from Object.java. It simply returns following:
getClass().getName() + "#" + Integer.toHexString(hashCode()
Hence the output.
See code here
What is the connection between System.out.println() and toString() in Java? e.g:
public class A {
String x = "abc";
public String toString() {
return x;
}
}
public class ADemo {
public static void main(String[] args) {
A obj = new A();
System.out.println(obj);
}
}
If main class runs, it gives an output as "abc". When I remove the code which overrides toString(), it gives an output as "A#659e0bfd". So, can anyone explain what is the working principle of System.out.println() when I pass the obj object reference as an argument to it? Is it fully connected with toString() method?
System.out is a PrintStream. Printstream defines several versions of the println() function to handle numbers, strings, and so on. When you call PrintStream.println() with an arbitrary object as a parameter, you get the version of the function that acts on an Object. This version of the function
...calls at first String.valueOf(x) to get the printed object's string value...
Looking at String.valueOf(Object), we see that it returns
if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
So, long story short, System.out.println(someObject) calls that object's toString() function to convert the object to a string representation.
If your object defines its own toString() function, then that is what will be called. If you don't provide such a function, then your object will inherit toString() from one of its parent classes. In the worst case, it will inherit Object.toString(). That version of toString() is defined to return
a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
Or, in other words:
getClass().getName() + '#' + Integer.toHexString(hashCode())
So, when you call System.out.println() on an object that doesn't define its own version of toString(), you might get the Object version which looks like "classname#someHexNumber".
toString() is a method that exist in the Object class (Root of the inheritence tree) for all classes.
System.out.print() (SOP) will call the toString method when fed an object.
If you don't overwrite the method toString(), SOP will call the parent toString() which, if parent is the Object class, it will print the hashCode of the object
If you overwrite the method, SOP will call your toString() method
System.out.println(obj) will print the returned string from obj.toString() if you dont override it it will call the base object.toString() method which by default the toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
When will this.toString() possibly return a duplicate String?
public static void main(java.lang.String s[]) {
for(int i=0;i<155000;i++) {
new Thread(new Runnable() {
public void run() {
System.out.println(this.toString());
}
}).start();
}
}
Thomas' answer is right in that Object's default toString() method will be called which produces different Strings for different objects.
One thing to note here. Object.toString() returns:
return getClass().getName() + "#" + Integer.toHexString(hashCode());
It includes Object.hashCode(). The Javadoc of hashCode() states:
...the hashCode method defined by class Object does return distinct integers for distinct objects...
The key is that hashCode() will be different for distinct objects. Since your code does not store the created Runnables, once the Threads are done, they will be garbage collected. Once an object is removed from memory, another Object may take its place in memory and it is possible that a new Runnable will provide the same hashcode that was returned by a previous Runnable which is now ceased to exist.
So theoretically it is possible that you will see the same String printed indeterministically (although the chances are very slim).
Since toString() by default just returns the class and object id, in your case there should never be duplicates. You're basically creating 155k different anonymous instances of Runnable (and Thread as well).
From the doc : The toString() method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
The toString() method you are using is of Object class. And as you can see, it involves hashCode, hence it will never print duplicate values,provided that, all the instances of your previous Runnable are still IN memory.
I have an object, Mutation, that I have "new"ed. But when it prints out with toString(), the object says Mutation#0. That doesn't seem good to me. What might that mean?
That is Unsigned hexadecimal representation
As per Docs of toString() method in Object class
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
That zero in the sense the Hashcode not yet calculated.
Source Code:
public String toString() {
237 return getClass().getName() + "#" + Integer.toHexString(hashCode());
238 }
If you look at the source code of Mutation, a good chance is you'll find this in there:
#Override public int hashCode() {
//TODO: implement this properly!
return 0;
}
The default implementation of toString() just reports this fact that hashCode returned 0.
What does the following System.out print in the following code??
class ExampleTest {}
public class Test {
public static void main(String ... strings){
ExampleTest et=new ExampleTest();
System.out.println(et);
System.out.println(new ExampleTest());
}
}
When you give any object to a print method, such as in your code, it will call the toString() method.
In your example, your ExampleTest class does not override this toString() method, so it will call the Object.toString():
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
So the output will be the full name of the class, and the result of the hashCode of this class.
Here is what the Javadoc of java.lang.Object.toString() says about that:
Returns a string representation of the
object. In general, the toString
method returns a string that
"textually represents" this object.
The result should be a concise but
informative representation that is
easy for a person to read. It is
recommended that all subclasses
override this method.
The toString method for class Object
returns a string consisting of the
name of the class of which the object
is an instance, the at-sign character
`#', and the unsigned hexadecimal
representation of the hash code of the
object. In other words, this method
returns a string equal to the value
of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
It prints the class name followed by the # symbol, followed by the unsigned hexadecimal representation of the object's hashcode.