본문 바로가기
Programming/Java

자바 정렬 Java Comparable Comparator 확실히 알고 넘어가기

by BePossible 2017. 1. 27.

배열이나 Collection 프레임워크 등에서 sort() 를 사용하면 컴퓨터가 알아서 정렬을 해준다.

여기서 사용되는 sort() 는 Comparable 구현에 의해 정렬된 것인데, 

오늘은 자바 정렬 Java Comparable과 Comparator에 대해 알아보고자 한다.


나도 여전히 공부중에 있으므로, 이해를 돕기 위해 배열 및 ArrayList 모두를 활용해 예제를 만들어봤다.



결과


먼저 Arrays.sort() 의 작동 결과를 보기 위한 코드를 만들어봤다.

String 타입의 배열을 만들었고, 거기에 대한 Arrays.sort() 를 해줬다.


영어는 ABC 순서대로, 한글은 가나다 순서대로 정렬이 된 모습을 확인할 수 있다.

Baseball,  Basketball 이나 Ski, Soccer 등 같은 알파벳으로 시작하는 단어들도 정확하게 정렬이 됐다.

한글의 경우 강동원, 김수현, 김우빈 등 ㄱ으로 시작하는 이름은 가나다순에 맞게 정렬이 된 모습이다. 


Comparable - 기본 정렬기준을 구현하는데 사용.

Comparator - 기본 정렬기준 외에 다른 기준으로 정렬하고자할 때 사용. 


여기서 Arrays.sort(sports), Arrays.sort(names)는 String 의 Comparable 구현에 의해 정렬된 것이다.

Comparable 을 구현하고 있는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 

String, Integer, Date, File 등과 같은 것들이다. 

그리고 기본적으로는 작은 값에서 큰 값의 순서, 오름차순 형태로 구현되도록 만들어져 있다.

이것을 상단 Comparable에 명시되어 있는 < 기본 정렬기준 > 으로 보면 될 것 같다. 





결과




이번엔 배열이 아닌 ArrayList 형태로 sort() 를 구현해보자.

상단 배열에서 했던 방식과 똑같지만 String 타입의 배열을 ArrayList로 바꿨다.

여기서는 Arrays.sort()가 아닌 Collections.sort() 를 적용해야 한다.


정렬 결과, 역시 A,B,C 순서대로 바르게 정렬이 됐다. 

기본 정렬기준에 만족하는 상태로 정렬이 된 것이다.





이제부터는 기본 정렬기준이 아닌 다른 정렬기준으로 시도해보자.

축구선수를 뜻하는 SoccerPlayer라는 클래스를 하나 만들고, 축구선수의 객체배열을 이용해 sort를 해보려고 한다.



SoccerPlayer는 이름, 포지션, 나이 속성을 갖고 있고 각각 setter와 getter를 선언해줬다. 

여기서 동일하게 SoccerPlayer 객체를 생성하고, 배열이나 ArrayList 형태로 만들었을 경우

Arrays.sort(), Collections.sort() 는 작동할까?


답부터 말하자면 오류가 발생한다.

이유는 정렬을 시도했지만, 객체내의 어떤 변수를 기준으로 정렬할지 정하지 않았기 때문.

String타입의 배열이나 ArrayList는 값이 하나지만, 객체를 정렬할 경우 객체 내의 어떤 변수로 정렬할지 만들어줘야 한다.


이때 Comparable을 implements한 뒤 compareTo 메소드를 구현한다면 해결할 수 있다.



SoccerPlayer 클래스에서 Comparable<SoccerPlayer>를 implements 하였다.

그리고 하단에는 compareTo를 오버라이드하여 코드를 따로 만들어줬다.

매개변수로 SoccerPlayer 객체를 받고,

리턴값으로는 객체의 이름을 비교하는 구문을 넣어줬다. 


여기서 본인이 정렬하고자 하는 클래스를 Comparable<클래스명> 형태로 넣어주는 것을 잊어서는 안된다.




결과


이제 메인함수에서 6명의 축구선수 객체를 생성한 뒤, ArrayList 에 추가했다.  (축구선수 나이는 임의로 정했으니 오해하지 말 것..ㅋㅋㅋ)

그 다음 Collections.sort(playerList) 를 이용해 정렬을 시도하니 가나다 이름순서로 정렬되어 나오는 것을 확인할 수 있다. 




감이 온다면 바로 이해가 됐을 것이다.

바로 SoccerPlayer 클래스에서 Comparable을 implements 했고, 하단에 compareTo를 Override하며 이름비교 코드를 만들어준 덕분이다.

이 부분을 이름순서가 아닌 나이순서로 바꿔줄 수도 있고, 포지션을 기준으로 해도 무방하다.

본인이 필요한 기준을 정해 코딩을 하면 끝.


Comparable을 implements 하지 않고도 오브젝트의 특정 변수를 기준으로 정렬하는 방법은 있다.

이 때 사용하는 방법이 바로 Comparator 이다. 

Comparator를 사용하면 정렬기준을 본인이 원하는대로 바꾸는 것이 가능하다. 



결과


SoccerPlayer 클래스에 Comparable을 implements하지 않은 상태로 메인함수 내에서 Collections.sort()를 만들었다. 

여기서는 Collections.sort(playerList, new Comparator<SoccerPlayer>() { } 형태로 구현해야 하며,

이때 compare 메소드가 나타나 내부 코딩을 마무리해야 한다. 


나는 축구선수의 나이순서대로 정렬이 되도록 구현했고, 결과는 정상적으로 나이 순서대로 나타났다. 

Comparable을 사용하든 Comparator를 사용하든 어떻게 구현하느냐에 따라 정렬이 진행되니 참고하길. 




결론

Comparable 구현 후 내부의 compareTo 메소드를 오버라이드해 정의해야 하는데, 이 정의 결과에 따라 정렬값이 나온다.

또한, 오브젝트의 다른 값으로 비교를 원한다면 compareTo를 하나하나 바꿔줄 필요 없이, Comparator를 이용하면 된다.


요약(?)

Collections.sort() , Arrays.sort() 등 ~~.sort()는 배열이나 리스트를 정렬할 때 Comparator를 지정하지 않았을 경우

Comprarable을 구현한 클래스의 객체에 구현된 내용에 따라 정렬!! 


자바 정렬 Java Comparable Comparator에 대해 두서없이 적어봤다.

직접 다 해보면 이해가 빠르니 코딩해보는걸 추천! 







댓글