본문 바로가기
Programming/> Java

[Java] Comparable, Comparator

by 니키ᕕ( ᐛ )ᕗ 2017. 10. 4.
 이것을 포스팅 하는 이유는 이전 포스팅인 Big Sorting에서 막혀서다.
int n = 6;
String[] unsorted = new String[] {"31415926535897932384626433832795", "1", "3", "10", "3", "5"};
// your code goes here
for (int i = 0; i < n - 1; i++) {
	int target = i;

	for (int j = i + 1; j < n; j++) {

		int targetLen = unsorted[target].length();
		int jLen = unsorted[j].length();
		
		if (targetLen > jLen) {
			target = j;
		} else if (targetLen == jLen) {
			
			for (int k = 0; k < targetLen; k++) {
				int tValue = Character.getNumericValue(unsorted[target].charAt(k));
				int jValue = Character.getNumericValue(unsorted[j].charAt(k));
				
				if(tValue != jValue && tValue > jValue) {
					target = j;
					break;
				}
			}
		}
	}
	
	if (target != i) {
		String temp = unsorted[target];
		unsorted[target] = unsorted[i];
		unsorted[i] = temp;
	}
}

 위와 같이 문제를 풀었더니 첫번째 샘플 케이스는 통과했지만 나머지는 우수수수수 Fail먹고 심지어 마지막 3개 케이스는 timeout이 나버렸다. 4초 걸렸나.... 포인트 써서 케이스 파라미터 열어봤더니 스크롤이 매~우 길었다. 

 

 

 처음에는 Selection Sorting에 BigInteger로 파싱해가면서 하다가 뭔가 아니다 싶어서 String을 쪼개서 값을 비교했는데... 방법은 맞는거 같지만 구현에 실패한 느낌이라 Discussions 들어가봤더니 다들 각 언어들이 자체적으로 가지고 있는 Sort 기능을 써서 풀고 있었다..... ! 전에 정렬 알고리즘 공부한다고 자료 찾아봤을 때 어차피 정렬 알고리즘에은 메소드로 다 구현되어 있으니 메소드를 쓰자... 라는 걸 봤는데 그게 생각났다. 

너무 구닥다리에 무식하게 시도한 것 같아서 Java에서 Sorting 할 때 사용하는 Comparator와 Comparable에 대해 이해한 것을 간단하게 정리해봄...   

 

● 공통점

두 객체를 비교하기 위한 인터페이스

 

● 차이점

▷ Comparable

public class Test implements Comparable<Test>{
	@Override
	public int compareTo(Test o) {
		// TODO Auto-generated method stub
		return 0;
	}
}

- 자연스러운 순서로 정렬을 위해 사용.

- compareTo 오버라이드하여 자기 자신과 동일한 클래스의 객체와 비교한다.

- 자기 자신이 앞에 오면 음수, 자기 자신과 비교 대상이 같으면 0, 비교 대상이 앞에 오면 양수 값을 리턴한다.

 

▷ Comparator

public class Test<T> implements Comparator<T>{
	@Override
	public int compare(T o1, T o2) {
		return 0;
	}
}

- 원하는 정렬 기준으로 정렬.

- compare 오버라이드하여 동일한 클래스의 외부의 두 객체를 비교한다.

- 첫번째 파라미터가 앞에 오면 음수, 같으면 0, 두번째 파라미터가 앞에 오면 양수 값을 리턴한다.

- 익명 클래스로 구현 가능.

Comparator<String> bigSortComparator = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.length() - o2.length();
        }
    };
Arrays.sort(arr, bigSortComparator);

 

● 탐구

 

- Primitive원시타입은 자연적인 순서가 존재하고 String은 Class로서 Comparable을 구현하고 Arrays나 Collections의 sort 메소드로 정렬하는 경우 ClassCastException이 발생하지 않음.

- 비교를 하려는 객체의 클래스가 Comparable을 구현하지 않고 클래스 내의 정렬 기준의 값이 Primitive원시타입 혹은Comparable로 구현된 Reference Type이 아니면 ClassCastException이 발생할 것.

- 근데 용례를 보면 Comparable도 결국 자연적인 순서 정렬을 위해서.. 라고 책에 나와있는데 compareTo를 구현해야하는 것을 보면 결국 자연적인 순서는 의미가 없는 듯

- 이렇게 생각을 하며 내린 결론은.. 자체적으로 클래스 내에 정렬 기준을 두고 싶은 경우엔 Comparable, 클래스 내에 딱히 정렬 기준을 두고 싶지 않거나 있더라도 간혹 다른 정렬 기준을 둬야할 것 같은 경우에는 Comparator를 구현하여 사용하면 될 것 같다.

 

 

[참조]

책 - Java 프로그래밍 면접 이렇게 준비한다.

 

'Programming > > Java' 카테고리의 다른 글

[Java] java.lang.UnsatisfiedLinkError Exception  (0) 2015.10.30
[Java] 콘솔 소켓 채팅 프로그램  (0) 2015.10.19
[java] Servlet & JSP 정리  (0) 2015.08.16
[java] jdk 환경변수 설정  (0) 2014.07.20

댓글