달력

92021  이전 다음

  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  •  
  •  

'CompareTo'에 해당되는 글 1건

  1. 2005.05.25 Comparable 인터페이스 이용해서 Object sort 하기..

예전에 어디다 적어놨던거 같은데... 찾으니 없어서 다시 적음 -.-;

간단한 것이지만 까먹고 나면 문서 찾아봐야 하고 해서 ...


그럼 본문 시작.......


java.util.Collections 클래스에는 sort(List list) 라는 정적 메소드와

sort(List list, Comparator c) 라는 메서드가 있다.


이넘들을 이용해서 객체를 정렬 할 수 있다..

문제는 사용자 정의 객체(대표적으로 Java Bean) 들은 정렬대상에서 제외 된다.

예를 들면..


class TestBean{
 int pk;
 String name;

 public void setPk(int pk){ this.pk = pk; }
 public int getPk(){ return pk; }
 public void setName(String name){ this.name = name; }
 public String getName(){ return name; }

 public String toString(){
  return "[pk = " + pk + " , name = " + name + "]";
 }

}


이런 클래스가 하나 있다.

이 클래스에는 pk 라는 변수가 있는데.. 이 번호를 기준으로 객체를 정렬하고 싶다.

main 메소드를 만들어 정렬을 수행해 보자..

import java.util.*;

public class CompareToTest{
 public static void main(String[] args){
 
  System.out.println("정렬정렬 김정렬..");
  List list = new ArrayList();

  int[] arr = new int[]{8,3,4,6,1,2,7,5,9};
  String[] name = new String[]{"a", "z","y", "k","l","o","t","q", "f"};

  TestBean bean = null;
  for(int i = 0; i < arr.length; i++){
   bean = new TestBean();
   bean.setPk(arr[i]);
   bean.setName(name[i]);

   list.add(bean);
  }

  System.out.println("정렬 전");

  for(int i = 0; i < list.size(); i++){
   bean = (TestBean)list.get(i);
   System.out.println(bean);
  }

  Collections.sort(list);  // <-- 여기서 정렬...

  System.out.println("정렬 후");
  for(int i = 0; i < list.size(); i++){
   bean = (TestBean)list.get(i);
   System.out.println(bean);
  }
 }
}


이 클래스를 실행하면...


정렬정렬 김정렬..
정렬 전
[pk = 8 , name = a]
[pk = 3 , name = z]
[pk = 4 , name = y]
[pk = 6 , name = k]
[pk = 1 , name = l]
[pk = 2 , name = o]
[pk = 7 , name = t]
[pk = 5 , name = q]
[pk = 9 , name = f]
java.lang.ClassCastException
 at java.util.Arrays.mergeSort(Arrays.java:1152)
 at java.util.Arrays.mergeSort(Arrays.java:1163)
 at java.util.Arrays.sort(Arrays.java:1079)
 at java.util.Collections.sort(Collections.java:113)
 at CompareToTest.main(CompareToTest.java:28)
Exception in thread "main"


이런 에러가 발생하게 된다..

에러가 발생하는 건 당연한 이야기 이다.

Collections.sort() 메서드에서 무슨 근거로.. List 안에 들어있는 객체들을 정렬하겠냐 말이쥐..

그럼 이걸 정렬되게 하려면 어떻게 하면 되나...


java.lang 패키지에 있는 Comparable 인터페이스를 구현하면 된다.


java.lang.Comparable 인터페이스에는 compareTo(Object o) 라는 메서드가 있다.

이 녀석을 재정의 하면 된다..

재정의 규칙은 다음과 같다.


o.pk 가 현재 PK 보다 크다면  1 을 반납

o.pk 가 현재 pk 보다 작다면 -1 을 반납

o.pk 가 현재 pk 와 같다면 0 을 반납.


이러면 모든게 끝난다.


그럼 수정한 예를 보자.

class TestBean implements Comparable{
 int pk;
 String name;

 public void setPk(int pk){ this.pk = pk; }
 public int getPk(){ return pk; }
 public void setName(String name){ this.name = name; }
 public String getName(){ return name; }

 public String toString(){
  return "[pk = " + pk + " , name = " + name + "]";
 }


 // 구현 메소드
 public int compareTo(Object o){
  TestBean bean = (TestBean)o;
 
  if(bean.pk < this.pk) return 1;
  else if(bean.pk > this.pk) return -1;
  else return 0;
 }
}


이 예제를 실행하면 아래와 같이 나올것이다..


정렬정렬 김정렬..
정렬 전
[pk = 8 , name = a]
[pk = 3 , name = z]
[pk = 4 , name = y]
[pk = 6 , name = k]
[pk = 1 , name = l]
[pk = 2 , name = o]
[pk = 7 , name = t]
[pk = 5 , name = q]
[pk = 9 , name = f]
정렬 후
[pk = 1 , name = l]
[pk = 2 , name = o]
[pk = 3 , name = z]
[pk = 4 , name = y]
[pk = 5 , name = q]
[pk = 6 , name = k]
[pk = 7 , name = t]
[pk = 8 , name = a]
[pk = 9 , name = f]


Collections.sort(List list) 외에 Arrays.sort(Object[] a) 도 같은 결과가 나온다.


TestBean 의 내부변수인 pk 로 정렬을 해보았다..

이 상태에서... name 으로 비교를 해 볼수도 있다.

방법은 아주 단순하고 간단하다.

바로 java.util.Comparator 인터페이스를 상속하여.. 새로운 클래스를 구현하고 그 클래스를 정렬하는 곳에 알려주면 된다.


java.util.Comparator 인터페이스에는 구현해야할 메소드가 두 개 있다.

public int compare(Object o1, Object o2)

public boolean equals(Object obj)


이렇게 두개만 구현해 주면 된다..


그럼 이름으로 정렬하기 위해 새로운 클래스를 하나 만들어보자.

class MyComparator implements Comparator{
 public int compare(Object o1, Object o2){
  return ((TestBean)o1).getName().compareTo(((TestBean)o2).getName());
 }
 
 public boolean equals(Object o){
  return true;
 }
}

그리고 테스트를 위해 main 메서드의 내부를 아래와 같이 수정했다.

import java.util.*;

public class CompareToTest{
 public static void main(String[] args){
 
  System.out.println("정렬정렬 김정렬..");
  List list = new ArrayList();

  int[] arr = new int[]{8,3,4,6,1,2,7,5,9};
  String[] name = new String[]{"a", "z","y", "k","l","o","t","q", "f"};

  TestBean bean = null;
  for(int i = 0; i < arr.length; i++){
   bean = new TestBean();
   bean.setPk(arr[i]);
   bean.setName(name[i]);

   list.add(bean);
  }

  //-------------------------
  // 추가된 부분
  //-------------------------
  TestBean temp = new TestBean();
  temp.setPk(1);
  temp.setName("m");
  list.add(temp);


  System.out.println("정렬 전");

  for(int i = 0; i < list.size(); i++){
   bean = (TestBean)list.get(i);
   System.out.println(bean);
  }

  Collections.sort(list);

  System.out.println("정렬 후");
  for(int i = 0; i < list.size(); i++){
   bean = (TestBean)list.get(i);
   System.out.println(bean);
  }

  //-------------------------
  // 추가된 부분
  //-------------------------

  Collections.sort(list, new MyComparator()); 

  System.out.println("Comparator 구현 후");
  for(int i = 0; i < list.size(); i++){
   bean = (TestBean)list.get(i);
   System.out.println(bean);
  }
 }
}



이 클래스를 실행하면 아래와 같은 결과가 나온다...


정렬정렬 김정렬..
정렬 전
[pk = 8 , name = a]
[pk = 3 , name = z]
[pk = 4 , name = y]
[pk = 6 , name = k]
[pk = 1 , name = l]
[pk = 2 , name = o]
[pk = 7 , name = t]
[pk = 5 , name = q]
[pk = 9 , name = f]
[pk = 1 , name = m]
정렬 후
[pk = 1 , name = l]
[pk = 1 , name = m]
[pk = 2 , name = o]
[pk = 3 , name = z]
[pk = 4 , name = y]
[pk = 5 , name = q]
[pk = 6 , name = k]
[pk = 7 , name = t]
[pk = 8 , name = a]
[pk = 9 , name = f]
Comparator 구현 후
[pk = 8 , name = a]
[pk = 9 , name = f]
[pk = 6 , name = k]
[pk = 1 , name = l]
[pk = 1 , name = m]

[pk = 2 , name = o]
[pk = 5 , name = q]
[pk = 7 , name = t]
[pk = 4 , name = y]
[pk = 3 , name = z]



훔.. 말주변이 없어서 더이상 설명이 안되네.....

머 두개의 클래스(TestBean 과 MyComparator ) 를 합쳐서 지지고 볶구 해도 되겠징.. ^^;

또는 보기 좋게~ static 메서드로 만들어도 되겠고..

또는...

또는...

또는...

또는....

또는......


머리 깨지네 ㅋ

Posted by Tornado tornado

댓글을 달아 주세요