Question

The Following program prints one|two one|two when HashSet is used. If I change it to TreeSet it prints only one|two

Is it not expected to give the same result with the same set of data ?What am I doing wrong here? What in the program makes the second record duplicate in case of TreeSet?

import java.util.HashSet; import java.util.Set;

public class SetTest {

public static void main(String arg[]) {
    Set<Bk> bookList = new HashSet<Bk>();
            //Set<Bk> bookList = new TreeSet<Bk>();
    bookList.add(new Bk("one","two"));
    bookList.add(new Bk("one","two"));
    for(Bk book: bookList){
        System.out.println(book);
    }
}
}

class Bk implements Comparable<Bk> {


public String name;
public String author;

public String toString(){
    return name+"|"+ author;
}

Bk(String name, String author) {
    this.name = name;
    this.author = author;

}

@Override
public int compareTo(Bk that) {

    int author = this.author.compareTo(that.author);
    int name = 0;
    if (author == 0) {
        name = this.name.compareTo(that.name);
        return name;
    } else {
        return author;
    }

}

}

Was it helpful?

Solution

The HashSet class will use hashCode and equals to determine if there is a duplicate already in the set. The TreeSet class will use the fact that it's Comparable (or alternatively, a Comparator) to order items and determine if there's a duplicate.

You have Bk as Comparable<Bk>, so TreeSet will work properly with it. But, you still need to override hashCode and equals so HashSet will work properly with it also.

OTHER TIPS

If you want consistent behaviour with a HashSet you would have to implement hashCode() and equals(), as per the Javadoc, and in such a way as to be consistent with your compareTo() method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top