ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] HeadFirst 16장 : Comparable, Comparator 와 Sort
    JAVA 2012. 2. 28. 12:05

    Collection 이나 Map에서 제네릭 ( <클래스명>  이런거) 을 사용한다.

    내가 만든 클래스의 인스턴스를 자료구조 내에서 정렬 시킬때 어떤 맴버변수 기준으로 정렬할지 정해야 하는데

    이때 아래와 같이 Comparable을 implements 하고 compareTo 메소드를 구현하면

    Song이 항목으로 들어간 자료구조를 Collections.sort()로 정렬할때
    Song 내부에서 구현한 compareTo를 사용하여 정렬한다.
    title을 기준으로 하고 싶으면 compareTo에서 title로 비교하고,
    artist로 비교하고 싶으면 artist 멤버변수로 compareTo를 구현하면 된다.

    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 내부에서 comparable을 implements하여 구현하지 않고도 정렬하는 또다른 방법은
    아래와 같이 Comparator 를 imlements하는 비교를 위한 별도의 클래를 만들면된다.

    package chap16.practice;

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileReader;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;

    public class Jukebox5 {
     ArrayList<Song> songList = new ArrayList<Song>();

     public static void main(String[] args) {
      new Jukebox5().go();
     }

     class ArtistCompare implements Comparator<Song> {
      public int compare(Song one, Song two) {
       return one.getArtist().compareTo(two.getArtist());
      }
     }

     public void go() {
      getSong();
      System.out.println(songList); 
      Collections.sort(songList); // song class에서 구현한 compare를 사용하여 정렬 (title기준 정렬)
      System.out.println(songList); 

      ArtistCompare artistCompare = new ArtistCompare();
      Collections.sort(songList, artistCompare); // ArtistCompare class에서 구현한 compare로 정렬 (artist 기준 정렬)
      
      System.out.println(songList);
     }

     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);
     }
    }




    정렬기준을 여러번 바꾸고 싶으면 아래와 같이 비교를 위한(Comparator를 구현한) 클랙스를 여러개 만들어 쓰면된다.

    package chap16.practice;

    import java.util.Collections;
    import java.util.Comparator;
    import java.util.LinkedList;

    public class SortMountains {

     LinkedList<Mountain> mtn = new LinkedList<Mountain>(); 
     
     class NameCompare implements Comparator<Mountain> {
      public int compare(Mountain one, Mountain two) {
       return one.getName().compareTo(two.getName());
      }
     }
     
     class HeightCompare implements Comparator<Mountain> {
      public int compare(Mountain one, Mountain two) {
       return two.getHeight() - one.getHeight(); // one이 크면 음수, two가 크면 양수
      }
     }
     
     public static void main(String[] args) {
      new SortMountains().go();
     }
     
     public void go() {
      mtn.add(new Mountain("Longs", 14255));
      mtn.add(new Mountain("Elbert", 14433));
      mtn.add(new Mountain("Maroon", 14156));
      mtn.add(new Mountain("Castle", 14265));
      
      System.out.println("as entered:\n" + mtn);
      NameCompare nc = new NameCompare();
      Collections.sort(mtn, nc);
      System.out.println("by name:\n" + mtn);
      HeightCompare hc = new HeightCompare();
      Collections.sort(mtn, hc);
      System.out.println("by height:\n" + mtn);  
     }

     class Mountain {
      String name;
      int height;
      
      public Mountain(String name, int height) {
       this.name = name;
       this.height = height;
      }
      
      public String getName() {
       return name;
      }
      
      public int getHeight() {
       return height;
      }
      
      public String toString() { // 와.. 클래스 안에 이거 없으니까.. 화면출력시 bytecode로 나옴;;ㄷㄷㄷ
       return name + " " + height;
      }
     }
    }


    여기서 한가지 클랙스 내부의 맴버변수를 print함수로 출력할때
    toSting 함수가 없으면 bytecode로 나오니..
    toString 구현하는걸 잊지 말기를..

Designed by Tistory.