Page 1 of 1

About Question enthuware.ocpjp.v8.2.1298 :

Posted: Thu Dec 17, 2015 11:07 am
by mrmuiz
Object class's hashCode method returns unique hashcode for every object
That's not true, jvm will do the best to return well distribute integers, so that it is very unlikely for two objects considered different (according to equals() method) to have the same hashcode, but it's not impossible.

If you let this program run for some time

Code: Select all

        Object tmp,target = new Object();
        int targetHash = target.hashCode();
         
        do	tmp = new Object();
        while (tmp.hashCode() != targetHash);
        
        System.out.println("tmp.equals(target) = "+tmp.equals(target));
        System.out.println("tmp.hashCode() = "+tmp.hashCode());
        System.out.println("target.hashCode() = "+target.hashCode());
you'll end up with something like

Code: Select all

tmp.equals(target) = false
tmp.hashCode() = 1704856573
target.hashCode() = 1704856573
In fact, there's a remote possibility for the code in the question to print "10, 10".

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Mon Dec 21, 2015 3:36 am
by admin
While what you say is technically correct, such border cases will always be there in everything and it is not really practical to add such disclaimers everywhere. For example, if there is a statement that says which method returns random numbers and the answer says Math.random, you could argue that it doesn't really return truly random numbers.
Or you can have strings of unlimited length in Java? Of course, this is subject to available memory.

In this case also, even the API says, "As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects."

Everything has some or the other limitation. It does not make sense to take focus away from the general concept to some that is not very important for this exam.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Mon Dec 21, 2015 6:58 am
by mrmuiz
I agree with you, that's an interesting topic. I find the javadoc to be a bit misleading, (more than) 10 years ago a bug was opened about this http://bugs.java.com/bugdatabase/view_b ... id=6321873

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Tue Jun 21, 2016 12:25 pm
by johnlong
I am not getting exception at runtime for the same example, could you take a look?

Code: Select all

import java.util.HashMap;
import java.util.Map;

class Bookk{

	String name;
	String ISBN;	
	@Override
	public boolean equals(Object obj){
		return this.ISBN.equals(((Bookk) obj).ISBN);
	}}

	class BookStore{		
		Map<Bookk,Integer> map = new HashMap<>();			
		void addToMap(Bookk b, int count){
			map.put(b, count);}
		int getCount(Bookk b){
			return map.get(b);}	
	}

public class HashMapTest {
	
	public static void main(String[] args) {		
		BookStore bs = new BookStore();			
		Bookk book = new Bookk();		
		book.ISBN = "111";	 bs.addToMap(book, 5);			
		System.out.println(bs.getCount(book));
		book = new Bookk();
		book.ISBN = "111";	bs.addToMap(book, 10);	
		System.out.println(bs.getCount(book));		
	}
}

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Tue Jun 21, 2016 12:47 pm
by admin
Remove the line bs.addToMap(book, 10);

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Tue Jun 21, 2016 3:57 pm
by johnlong
Thank you.

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Tue Mar 05, 2019 9:18 pm
by biswas_enthu
I have understood the explanation. Now I modified the code little bit to do experiment. I have made getNumberOfCopies() method's return type Integer instead of int, so that System.out.println(bs.getNumberOfCopies(b)) (last line) will print null instead of throwing NullPointerExcpetion. Now I am overriding hashCode() method so that it returns same hashCode value for same isbn. But still printing null. Below is my code.
Could you please explain why it is printing null? If hasCode method is not correctly overriden, could you please provide the correct one?

Code: Select all

package test;

import java.util.HashMap;
import java.util.Map;

class Book1{
	private String title, isbn;
	public void setTitle(String title) {
		this.title = title;
	}
	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}
	public boolean equals(Object o) {
		return (o instanceof Book && ((Book1)o).isbn.equals(this.isbn));
	}
	
	@Override
	public int hashCode() {
		return isbn.hashCode();
	}
}

class BookStore{
	Map<Book1, Integer> map = new HashMap<Book1, Integer>();
	Integer getNumberOfCopies(Book1 b) {
		return map.get(b);
		
	}
	
	public void addBook(Book1 b, int numberOfCopies) {
		map.put(b, numberOfCopies);
	}
}

public class HashCodeAndEqualTest {
	
	static BookStore bs = new BookStore();

	public static void main(String[] args) {
		Book1 b = new Book1();
		b.setIsbn("111");
		bs.addBook(b, 10);
		System.out.println(bs.getNumberOfCopies(b));
		b = new Book1();
		b.setIsbn("111");
		System.out.println(bs.getNumberOfCopies(b));

		
	}

}

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Tue Mar 05, 2019 10:02 pm
by admin
In your equals method you are using Book instead of Book1.

Re: About Question enthuware.ocpjp.v8.2.1298 :

Posted: Wed Mar 06, 2019 12:34 am
by biswas_enthu
Thank you for identifying the error spot. It worked after changing Book to Book1 in equals method.