JAVA

[JAVA] HeadFirst 16장 : HashSet, hashcode, equal

ShineWithMe 2012. 2. 29. 12:04

그냥 자료구조만 HashSet으로 써서 출력을 해보면

public class Jukebox6 {
 ArrayList<Song> songList = new ArrayList<Song>();
 
 public void go() {
  getSong();
  System.out.println(songList);
  Collections.sort(songList);
  System.out.println(songList);
  HashSet<Song> songSet = new HashSet<Song>();
  songSet.addAll(songList);
  System.out.println(songSet);  
 }
 
 public static void main(String[] args) {
  new Jukebox6().go();
 }

 void getSong() {
  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 e) {
   e.printStackTrace();
  }
 }

 void addSong(String lineToParse) {
  String[] tokens = lineToParse.split("/");
  Song s = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
  songList.add(s);
 }
}

아래와 같이 중복제거가 안되어 있다.
[Pink Moon, Somersault, Shiva Moon, Circles, Deep Channel, Passenger, Listen, Listen, Listen, Circles]
[Circles, Circles, Deep Channel, Listen, Listen, Listen, Passenger, Pink Moon, Shiva Moon, Somersault]
[Circles, Shiva Moon, Listen, Deep Channel, Passenger, Pink Moon, Listen, Somersault, Listen, Circles]


Song 클래스에서 HashMap에서 해시코드, 객체를 비교할 기준을 마련해 줘야한다.
(* 해시코드가 같아도 객체가 다를 수 있다. 그래서 두 개 기준모두 정해줘야한다.)
그래서 아래 equals와 hashCode를 오버라이드하여 구현한것이다.


public class Song implements Comparable<Song> {
 String title;
 String artist;
 String rating;
 String bpm;
 
 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;
 }
 public int compareTo(Song s) { //제네릭을 사용하여 자료구조에서 정렬할대 title을 기준으로 정렬한다.
  return title.compareTo(s.getTitle());
 }


 // Song 객체를 equals로 비교할땐 title기준으로 비교하도록 equals 오버라이드 구현
 public boolean equals(Object aSong) {   Song s = (Song) aSong;
  return getTitle().equals(s.getTitle()); // String에서 equals 메소드 오버라이드 되어 있어서 그냥쓰면됨
 }

 // 해시코드 값이 같은지 비교할때 Song의 title(String) 기준으로 해시코드 값을 비교하도록 오버라이드 구현
 public int hashCode() {
  return title.hashCode(); // 여기도 마찬가지 String에서 equals 메소드 오버라이드 되어 있어서 그냥쓰면됨
 }
}

출력해보면 아래와 같이 제대로 중복제거 된 것을 볼 수 있다.

[Pink Moon, Somersault, Shiva Moon, Circles, Deep Channel, Passenger, Listen, Listen, Listen, Circles]
[Circles, Circles, Deep Channel, Listen, Listen, Listen, Passenger, Pink Moon, Shiva Moon, Somersault]
[Listen, Circles, Somersault, Shiva Moon, Passenger, Pink Moon, Deep Channel]