정렬
우리는 정렬에 관해서 배우기도 하였고 구현도 해보았습니다. 그래서 어떻게 정렬이 되는지 알고 있죠. 하지만 실제 프로그래밍하는 상황에서 이 정렬을 직접구현해서 프로그램을 만들지는 않을 거에요. 우리에겐 JAVA에서 제공하는 정렬 메소드가 있기 때문이죠. 저희보다 똑똑한 사람들이 만들어 놓은 것이니 우리는 그저 감사하며 사용하면됩니다. 그 전에 사용법을 알아야 잘 사용할 수 있겠죠? 이제부터 어떻게 사용하는지 알아보도록 합시다.
Collections.sort
Collections.sort의 메소드를 이용해서 정렬할 수 있습니다. 바로 기본 자료형의 wrapper 클래스의 객체들은 전부 이 Collections.sort를 통해서 알아서 정렬이 가능합니다.
바로 예제를 통해 확인하도록 하지요.
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class Sort {
public static void printList(String title,List list){
System.out.println(title);
System.out.println(list);
}
public static void main(String []ar){
List<Integer> intList=new ArrayList<>();
intList.add(4);
intList.add(5);
intList.add(1);
intList.add(8);
intList.add(3);
printList("정수 정렬 전",intList);
Collections.sort(intList);
printList("정수 정렬 후",intList);
System.out.println("==============================");
List<String> strList=new ArrayList<>();
strList.add("de");
strList.add("dc");
strList.add("ci");
strList.add("ad");
strList.add("aa");
printList("문자열 정렬 전",strList);
Collections.sort(strList);
printList("문자열 정렬 후",strList);
}
}
정렬이 잘되는 것을 아래의 결과를 통해서 확인할 수 있네요.
실행결과 정수 정렬 전 |
Collections와 ArrayList를 이용한 객체 정렬
하지만 우리는 기본 자료형을 정렬하는 것이 아닌 우리가 만든 클래스의 객체를 정렬하려는 상황이 발생한다면 어떻게 하면 좋을까요?
아래와 같은 User라는 클래스가 있다고 칩시다.
class User{
public String name;
public int age;
public User(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "(name:"+name+", age:"+age+")";
}
}
그리고 이 클래스의 객체를 리스트에 5개를 담도록 하겠습니다.
List<User> list=new ArrayList();
list.add(new User("A",40));
list.add(new User("B",25));
list.add(new User("C",10));
list.add(new User("D",30));
list.add(new User("E",26));
System.out.println(list);
그리고 출력한다면 뭐 뻔한 결과가 나올테죠.
실행결과 [(name:A, age:40), (name:B, age:25), (name:C, age:10), (name:D, age:30), (name:E, age:26)] |
이 User의 객체들을 나이순으로 정렬하고 싶습니다(참고로 꼰대는 아니구요). 어떻게 정렬할 수 있을까요?
Comparator 구현
Collections.sort를 입력했을때 eclipse에 나오는 recommended method의 2번째 메소드를 보시기바랍니다. Comparator라는 객체를 받고 있는 것을 확인할 수 있습니다.
네, 답은 Comparator를 구현하면 이 상황을 해결할 수 있습니다.
그러면 바로 구현해보도록 합시다. 구현할 것이 메소드 하나 compare밖에 없어요. 그 내부 코드양도 얼마되지 않습니다.
class UserComparator implements Comparator<User>{
@Override
public int compare(User a,User b){
if(a.age>b.age) return 1;
if(a.age<b.age) return -1;
return 0;
}
}
compare는 2개의 인자를 받는데 이 인자들은 우리가 앞서 구현했던 User객체입니다. 만약 a라는 객체가 b라는 객체보다 더 크다면 1, 작다면 -1, 같다면 0을 반환하도록 합니다. 이게 오름차순의 방법이고, 만약 내림차순으로 구현하고 싶다면 반대로 구현하면 되겠죠? (모르면 그냥 찍어서 return하고 원하는 결과와 반대다 싶으면 return을 반대로 해줍시다^^.)
오름차순 |
첫번째 인자가 더 큰 객체라면 1 두번째 인자가 더 큰 객체라면 -1 같다면 0 |
내림차순 |
첫번째 인자가 더 작은 객체라면 1 두번째 인자가 더 작은 객체라면 -1 같다면 0 |
이 클래스의 객체를 Collections.sort의 2번째 인자로 전달하기만 하면 됩니다. 이제 전체코드와 결과를 보겠습니다.
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Sort {
public static void main(String[] ar){
List<User> list=new ArrayList();
list.add(new User("A",40));
list.add(new User("B",25));
list.add(new User("C",10));
list.add(new User("D",30));
list.add(new User("E",26));
System.out.println("정렬 전 ->"+list);
Collections.sort(list,new UserComparator());
//list.sort(new UserComparator()); 이 방법 역시 정렬 방법
System.out.println("정렬 후->"+list);
}
}
class User{
public String name;
public int age;
public User(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString(){
return "(name:"+name+", age:"+age+")";
}
}
class UserComparator implements Comparator<User>{
@Override
public int compare(User a,User b){
if(a.age>b.age) return 1;
if(a.age<b.age) return -1;
return 0;
}
}
실행결과 정렬 전 ->[(name:A, age:40), (name:B, age:25), (name:C, age:10), (name:D, age:30), (name:E, age:26)] |
저희가 원하던 결과를 얻을 수 있습니다. 참고로 Collections.sort를 주석처리하고 list.sort를 실행해도 결과는 같습니다. List도 역시 Comparator를 받을 수 있으니까요.
'언어 > JAVA' 카테고리의 다른 글
[Collection] 이것만 알면 해시맵(HashMap) 정복 가능 - HashMap의 특징, 사용법 예제 (2) | 2021.03.29 |
---|---|
[JAVA] SimpleDateFormat과 Date로 간단하게 시간 표시하기 (3) | 2020.06.30 |
[자바/JAVA] StringTokenizer를 이용해 문자열을 쪼개보자 (1) | 2020.03.02 |
[자바/JAVA] 쓰레드 동기화 (Thread Synchronization), synchronized (0) | 2019.12.07 |
[JAVA/자바] 쓰레드(Thread) 다루기( Thread상속, Runnable 구현, join) (3) | 2019.12.07 |