Hi!

I try to create HashSet of the next object:

import java.nio.file.Path;


public class WatchedPath {
	public Path dir;
	public boolean recursive;
	public Filter filter;
	
	// Ctor with only Path - for comparing between the object (comparing is only by the path!)
	public WatchedPath(Path dir) {
		this.dir = dir;
	}
		
	// Ctor without filter
	public WatchedPath(Path dir, boolean rec) {
		this.dir = dir;
		recursive = rec;
		filter = null;
	}

	// Ctor with filter
	public WatchedPath(Path dir, boolean rec, Filter filter) {
		this.dir = dir;
		recursive = rec;
		this.filter = filter;
	}

	// hashCode function
	public int hashCode () {
		return dir.hashCode();
	}
	
	
	// override the equals method! comparing is only by the path!
	public boolean equals(WatchedPath wp) {
		return dir.equals(wp.dir);
	}
	
	// override compareTo
	public int compareTo(WatchedPath wp) {
		return dir.compareTo(wp.dir);
	}
	
}

I thought the Hash's comparison between two object should be by their equals method, but for example, the next code will print nothing:

HashSet<WatchedPath> xx = new HashSet<WatchedPath>();
xx.add(wp); // wp is WatchedPath object.
if (xx.contains(new WatchedPath(wp.dir)))
	System.out.println("EQUALS!!!");

why does it happens?
what should I do for makaing the code print the text?

(my original problem is in BiMap, but I guess it's gonna have the same solution)

Thanks,
Nate

I thought the Hash's comparison between two object should be by their equals method,

The comparison is within the hash bucket, if two objects return the same hashcode then only the equality check by equals() takes place as mentioned below on http://www.ibm.com/developerworks/java/library/j-jtp05273.html

The interface contract for Object requires that if two objects are equal according to equals(), then they must have the same hashCode() value. Why does our root object class need hashCode(), when its discriminating ability is entirely subsumed by that of equals()? The hashCode() method exists purely for efficiency. The Java platform architects anticipated the importance of hash-based collection classes -- such as Hashtable, HashMap, and HashSet -- in typical Java applications, and comparing against many objects with equals() can be computationally expensive. Having every Java object support hashCode() allows for efficient storage and retrieval using hash-based collections.

So in the end my advice is check if the hashcode returned by the two objects is the same.

Hi!

I try to create HashSet of the next object:

import java.nio.file.Path;


public class WatchedPath {
	public Path dir;
	public boolean recursive;
	public Filter filter;
	
	// Ctor with only Path - for comparing between the object (comparing is only by the path!)
	public WatchedPath(Path dir) {
		this.dir = dir;
	}
		
	// Ctor without filter
	public WatchedPath(Path dir, boolean rec) {
		this.dir = dir;
		recursive = rec;
		filter = null;
	}

	// Ctor with filter
	public WatchedPath(Path dir, boolean rec, Filter filter) {
		this.dir = dir;
		recursive = rec;
		this.filter = filter;
	}

	// hashCode function
	public int hashCode () {
		return dir.hashCode();
	}
	
	
	// override the equals method! comparing is only by the path!
	public boolean equals(WatchedPath wp) {
		return dir.equals(wp.dir);
	}
	
	// override compareTo
	public int compareTo(WatchedPath wp) {
		return dir.compareTo(wp.dir);
	}
	
}

I thought the Hash's comparison between two object should be by their equals method, but for example, the next code will print nothing:

HashSet<WatchedPath> xx = new HashSet<WatchedPath>();
xx.add(wp); // wp is WatchedPath object.
if (xx.contains(new WatchedPath(wp.dir)))
	System.out.println("EQUALS!!!");

why does it happens?
what should I do for makaing the code print the text?

(my original problem is in BiMap, but I guess it's gonna have the same solution)

Thanks,
Nate

first of all you are not overriding ur compareTO method , because u r not implementing comparable, anyways compareTO will not play any roll here.
do one thing return 1; in ur hashcode method and execute the same code. I am not able to do anything in ur code as m using java 5 and I think u r using java7
import java.nio.file.Path; is not thr in java5

it's still not working.

like before. the next code print the blah blah...

if (wp.hashCode() == (new WatchedPath(wp.dir)).hashCode())
	System.out.println("ttttttttt");

if ((new WatchedPath(wp.dir)).equals(wp)) 
             System.out.println("eeeeeeeeee");

and the next code print nothing...:

HashSet<WatchedPath> xx = new HashSet<WatchedPath>();xx.add(wp); // wp is WatchedPath object.if (xx.contains(new WatchedPath(wp.dir)))	System.out.println("EQUALS!!!");HashSet<WatchedPath> xx = new HashSet<WatchedPath>();
xx.add(wp); // wp is WatchedPath object.
if (xx.contains(new WatchedPath(wp.dir)))
	System.out.println("EQUALS!!!");

I must solve this problem!!!

HashSet uses hashCode and equals as already stated. Also, as already stated, test the hashCode and equals outputs of Path, and ensure that you are getting what you expect, and ensure that the problem does not lie there.

HashSet uses hashCode and equals as already stated. Also, as already stated, test the hashCode and equals outputs of Path, and ensure that you are getting what you expect, and ensure that the problem does not lie there.

here is a code. the hashcode and equal are OK.
how do yoy explain the output:
2222222
3333333

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;


public class WatchedPath {
	public Path dir;
	public boolean recursive;
	
	// Ctor with only Path - for comparing between the object (comparing is only by the path!)
	public WatchedPath(Path dir) {
		this.dir = dir;
	}
		
	// Ctor with rec
	public WatchedPath(Path dir, boolean rec) {
		this.dir = dir;
		recursive = rec;
	}

	// hashCode function
	public int hashCode () {
		return dir.hashCode();
	}
	
	// override the equals method! comparing is only by the path!
	public boolean equals(WatchedPath wp) {
		return dir.equals(wp.dir);
	}


	public static void main(String[] args) throws IOException {
		String s = File.pathSeparator;
		Path p = Paths.get("c:"+s+"Users"+s+"NLG");
		WatchedPath wp = new WatchedPath(p, true);
		
		HashSet<WatchedPath> xx = new HashSet<WatchedPath>();
		xx.add(wp);
		if (xx.contains(new WatchedPath(wp.dir)))
			System.out.println("1111111");
		
		if (wp.hashCode() == (new WatchedPath(wp.dir)).hashCode())
			System.out.println("2222222");

		if ((new WatchedPath(wp.dir)).equals(wp)) {
			System.out.println("3333333");
		}		
	}
	
}

Because you wrongly overrode equals. Add the "@Override" annotation above every method that is suppossed to override something and you would notice that. The "equals" method needs to take "Object" as the parameter, not "WatchedPath".

Edit: And, obviously, you should then check that are actually getting a "WatchedPath, and not something else, and, regardless, you should also check that it is not null.

Edit Again: As well as checking that "dir" is not null, before calling equals and/or hashCode, and/or CompareTo on it, of course. And, for the compareTo to be used properly, don't forget to implement Comparable.

commented: Ahh... Missed the equals() method signature +5

Because you wrongly overrode equals. Add the "@Override" annotation above every method that is suppossed to override something and you would notice that. The "equals" method needs to take "Object" as the parameter, not "WatchedPath".

Edit: And, obviously, you should then check that are actually getting a "WatchedPath, and not something else, and, regardless, you should also check that it is not null.

Edit Again: As well as checking that "dir" is not null, before calling equals and/or hashCode, and/or CompareTo on it, of course. And, for the compareTo to be used properly, don't forget to implement Comparable.

Amazing!!!

Thanks!!!
-Nate

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.