This discussion is archived
11 Replies Latest reply: Oct 31, 2008 3:32 AM by 800282 RSS

Getting duplicate values in hashset???

843785 Newbie
Currently Being Moderated
The program jukebox parses the file SongListMore and gives the title as output.For Arraylist and collections we get unsorted and sorted output with duplicates which is desired. But for hashset I expect only non duplicate output(sorting doesn?t matter) which is not happening. Unable to figure out why?

Can u please help in here
Class Song
package com.mastek.first;

class Song implements Comparable<Song> {
     String title;
     String artist;
     String rating;
     String bpm;
     
     public boolean equals(Object aSong){
          Song s = (Song) aSong;
          System.out.println(s.getTitle());
          System.out.println(getTitle());
          //return getTitle().equals(s.getTitle());
          return false;
     }
     
     public int hashcode(){
          System.out.println(title.hashCode());
          return title.hashCode();
     }
     
     public int compareTo(Song s){
          return title.compareTo(s.getTitle());
     }
     
     Song(String t, String a, String r, String b){
          title = t;
          artist = a;
          rating = r;
          bpm = b;
     }
     
     public String getTitle(){
          return title;
     }
     
     public String getArtist(){
          return artist;
     }
     
     public String getRating(){
          return rating;
     }
     
     public String getBpm(){
          return bpm;
     }
     
     public String toString(){
          return title ;
     }

}
Class jukebox
package com.mastek.first;

import java.util.*;
import java.io.*;

public class Jukebox6 {
     
     ArrayList<Song> songList = new ArrayList<Song>();
     
     public static void main(String[] args) {
          // TODO Auto-generated method stub
          new Jukebox6().go();

     }
     
     public void go(){
          getSongs();
          System.out.println(songList);  /* unsorted  */
          
          Collections.sort(songList);
          System.out.println(songList);  /* sorted  */
          
          HashSet<Song> songSet = new HashSet<Song>();
          songSet.addAll(songList);
          System.out.println(songSet); /* should give output without duplicates */
     }
     
     void getSongs(){
          try{
               File file = new File("SongListMore.txt");
               BufferedReader reader = new BufferedReader(new FileReader(file));
               String line = null;
               while((line = reader.readLine()) != null){
                    addSong(line);
               }
          } catch(Exception ex){
               ex.printStackTrace();
          }
     }
     
     void addSong(String lineToParse){
          String[] tokens = lineToParse.split("/");
          
          Song nextSong = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
          songList.add(nextSong);
     }

}
text file data is as below:

Pink Moon/Nick Drake/5/80
Somersault/Zero 7/4/84
Shiva Moon/Prem Joshua/6/120
Circles/BT/5/110
Deep Channel/Afro Celts/4/120
Passenger/Headmix/4/100
Listen/Tahiti 80/5/90
Listen/Tahiti 80/5/90
Listen/Tahiti 80/5/90
Circles/BT/5/110
  • 1. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    You don't seem to implement Song.equals() . A must if you override hashcode().
  • 2. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    Methinks that you should uncomment this line.
    //return getTitle().equals(s.getTitle());
  • 3. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    uncommented the same, still the duplicate entries are there.
  • 4. Re: Getting duplicate values in hashset???
    800282 Newbie
    Currently Being Moderated
    Mehta wrote:
    uncommented the same, still the duplicate entries are there.
    Well then they're not equal.
  • 5. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    sabre150 wrote:
    You don't seem to implement Song.equals() . A must if you override hashcode().
    Just a thought - because I really do not know! Can you use hashcode like that?
    public int hashcode(){
              System.out.println(title.hashCode());
              return title.hashCode();
         }
  • 6. Re: Getting duplicate values in hashset???
    DarrylBurke Guru Moderator
    Currently Being Moderated
    Just a thought - because I really do not know! Can you use hashcode like that?
    Well as the method to be overridden is hashCode, not hashcode, you can do pretty much anything you like there. This is where the @Override annotation would have caught the typo.

    The contract of equals and hashCode is that if equals returns true, the two instances must have the same hashCode. So if title is the only field considered for equals, it's perfecly correct to return the hash of title from hashCode.

    db
  • 7. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    Darryl.Burke wrote:
    Just a thought - because I really do not know! Can you use hashcode like that?
    Well as the method to be overridden is hashCode, not hashcode, you can do pretty much anything you like there. This is where the @Override annotation would have caught the typo.

    The contract of equals and hashCode is that if equals returns true, the two instances must have the same hashCode. So if title is the only field considered for equals, it's perfecly correct to return the hash of title from hashCode.

    db
    Thanks Darryl.
    @OP: there's your why!

    Can not grasp we did not see that! More coffee please!

    Edited by: phdk on 31-10-2008 12:02
  • 8. Re: Getting duplicate values in hashset???
    800282 Newbie
    Currently Being Moderated
    phdk wrote:
    sabre150 wrote:
    You don't seem to implement Song.equals() . A must if you override hashcode().
    Just a thought - because I really do not know! Can you use hashcode like that?
    public int hashcode(){
              System.out.println(title.hashCode());
              return title.hashCode();
         }
    Do you mean the System.out.println in it, or the fact that it's hashcode instead of hashCode? It's all ok, but if the class is to be stored in a hash based collection, then (of course) it should be hashCode. But still, you can stuff all kind of stuff in the hashCode method, as long as it returns an integer value.
  • 9. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    sabre150 wrote:
    You don't seem to implement Song.equals() . A must if you override hashcode().
    Please ignore this! I must be blind.
  • 10. Re: Getting duplicate values in hashset???
    843785 Newbie
    Currently Being Moderated
    Darryl.Burke wrote:
    Just a thought - because I really do not know! Can you use hashcode like that?
    Well as the method to be overridden is hashCode, not hashcode, you can do pretty much anything you like there. This is where the @Override annotation would have caught the typo.

    The contract of equals and hashCode is that if equals returns true, the two instances must have the same hashCode. So if title is the only field considered for equals, it's perfecly correct to return the hash of title from hashCode.

    db
    Can't believe we missed that. You should quit your job and become a compiler. ;-)
  • 11. Re: Getting duplicate values in hashset???
    800308 Newbie
    Currently Being Moderated
    Now there's a good -noob compiler error to add to that list ...
    "C:\Program Files\Java\jdk1.6.0_07\bin\javac.exe" -Xlint -d C:\Java\home\classes -cp c:\java\home\src;C:\Java\home\classes; C:\Java\home\src\forums\Jukebox.java 
    C:\Java\home\src\forums\Jukebox.java:33: You meant hashCode numbnutts!
      public int hashcode(){
                      ^
    1 error
    I seriously don't get why the Java-team decided that the @Override would be an optional annotation... I believe it could (and therefore should) be taken as gratis, especially for "the core API methods"... but them I'm not the poor sod who'd have to implement "all that special stuff" in the compiler. ;-)

    Cheers. Keith.