본문 바로가기
Programming/Java

[정렬] 2. Java 배열(Array)의 정렬(Sorting) - 오름차순,내림차순,Comparable, Comparator

by 우공80 2022. 11. 12.
728x90

Array 정렬

 

Java 배열(Array)의 정렬

2022.11.11 - [Programming/Java] - [정렬] 1. 버블 정렬(Bubble Sort) 알고리즘

 

[정렬] 1. 버블 정렬(Bubble Sort) 알고리즘

정렬 알고리즘의 가장 기초인 버블 정렬에 대해 알아보겠습니다. Java에서 제공되는 Arrays.sort()를 사용해도 되지만, 기본적인 알고리즘은 알아두는 것이 좋을 것 같습니다. 정렬 알고리즘 - 버블

woogong80.tistory.com


앞서 포스팅에서 버블 정렬을 알아봤지만, 매번 정렬하는 함수를 만들어 쓸 수 없으니, Java에서 제공하는 함수를 사용하는 방법을 알아봅니다.


오름차순 정렬

Java 배열은 Arrays.sort() 메서드를 사용하여 간단히 정렬할 수 있습니다.

아래 예제와 같이, Int, char, String 구분 없이 오름차순 정렬이 가능합니다.

int[] num = {1, 6, 4, 2, 3, 5};
char[] ch = {'B','D','E','C','A'};
String[] str = {"Bbb","Bdd","Eee","Ccc","Aaa"};

Arrays.sort(num);

System.out.print("Int형 오름차순 정렬: ");
for(int n:num) System.out.print(" "+n);
System.out.println("");

Arrays.sort(ch);
System.out.print("char형 오름차순 정렬: ");
for(char c:ch) System.out.print(" "+c);
System.out.println("");

Arrays.sort(str);
System.out.print("String형 오름차순 정렬: ");
for(String s:str) System.out.print(" "+s);
System.out.println("");

Output:

Int형 오름차순 정렬:  1 2 3 4 5 6
char형 오름차순 정렬:  A B C D E
String형 오름차순 정렬:  Aaa Bbb Bdd Ccc Eee

내림차순 정렬

내림차순은 Arrays.sort()에 인자로 정렬 방법을 넣어주면 됩니다.  javadoc을 보면 아래와 같이 Comparator를 넣어주라고 되어있습니다.

public static <T> void sort(T[] a, Comparator<? super T> c)

Comparator는 Interface이므로 구현해서 사용해야 하지만, Collections.reverseOrder()라는 메서드가 제공되고 있어서 이것을 그대로 Arrays.sort()에 인자로 넣어주면 됩니다.

Arrays.sort(num,Collections.reverseOrder());
System.out.print("Int형 내림차순 정렬: ");
for(int n:num) System.out.print(" "+n);
System.out.println("");

Arrays.sort(ch,Collections.reverseOrder());
System.out.print("char형 내림차순 정렬: ");
for(char c:ch) System.out.print(" "+c);
System.out.println("");

Arrays.sort(str,Collections.reverseOrder());
System.out.print("String형 내림차순 정렬: ");
for(String s:str) System.out.print(" "+s);
System.out.println("");

그런데, 이 코드를 실행하면 String형 외에는 오류가 발생합니다. Collections는 int, char, float, double, boolean과 같은 기본 타입은 사용하지 못하므로 기본형에 해당하는 wrapper class를 사용해야 합니다.( String은 Java 기본 타입이 아니므로 오류 발생하지 않음) 아래 코드와 같이 int 대신 Integer, char 대신 Character로 변경해주면 됩니다. 

Integer[] num = {1, 6, 4, 2, 3, 5};
Character[] ch = {'B','D','E','C','A'};
String[] str = {"Bbb","Bdd","Eee","Ccc","Aaa"};

Arrays.sort(num,Collections.reverseOrder());
System.out.print("Int형 내림차순 정렬: ");
for(int n:num) System.out.print(" "+n);
System.out.println("");

Arrays.sort(ch,Collections.reverseOrder());
System.out.print("char형 내림차순 정렬: ");
for(char c:ch) System.out.print(" "+c);
System.out.println("");

Arrays.sort(str,Collections.reverseOrder());
System.out.print("String형 내림차순 정렬: ");
for(String s:str) System.out.print(" "+s);
System.out.println("");

Output:

Int형 내림차순 정렬:  6 5 4 3 2 1
Character형 내림차순 정렬:  E D C B A
String형 내림차순 정렬:  Eee Ccc Bdd Bbb Aaa

일부 정렬

다음으로 배열의 일부만 정렬하는 것도 가능합니다.

public static void sort(int[] a, int fromIndex, int toIndex)

Arrays.sort에 인자로 시작과 끝 인덱스를 추가로 넣어주면 됩니다. 

        int[] num = {1, 6, 4, 2, 3, 5};
        //일부만 정렬  
        Arrays.sort(num,2,5);
        System.out.print("일부정렬: ");
        for(int n:num) System.out.print(" "+n);
        System.out.println("");

Output: 인덱스가 2인 4부터 인덱스가 5인 5까지만 정렬이 됩니다.

일부정렬:  1 6 2 3 4 5

 

728x90

 

객체 배열 정렬

객체에 대한 정렬도 가능합니다. 객체는 Comparable 또는 Comparator 인터페이스를 구현하여 정렬할 수 있습니다.
Comparable은 compareTo 메서드를, Comparator는 compare 메서드를 구현해야 합니다. 내부적으로 이진트리를 이용하며, 메서드 반환 값이 양수이면 오름차순 음수이면 내림차순으로 정렬할 수 있습니다.

1. Comparable 구현

여기서는 User 클래스의 no를 기준으로 정렬을 했습니다. 이때 this.no - o.no를 하면 오름차순 정렬이 되고, 여기에 -1을 곱하여 음수로 만들면 내림차순 정렬이 됩니다.

public class User implements Comparable<User>{
    int no;
    String name;

    public User(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public int compareTo(User o) {
        return this.no - o.no;
        //return (this.no - o.no)*-1;  //내림차순 정렬
    }
}
public class SortTest {

    public static void main(String[] args) {

        User[] userList = {
                new User(1,"Steve"),
                new User(5,"Tom"),
                new User(2,"Jane"),
                new User(4,"Henry"),
                new User(3,"Joker"),
        };

        Arrays.sort(userList);

        for(User i:userList) System.out.println(i.no+" "+i.name);
    }
}

Output: 오름차순일 때

1 Steve
2 Jane
3 Joker
4 Henry
5 Tom

Output: 내림차순일 때

5 Tom
4 Henry
3 Joker
2 Jane
1 Steve

위 예에서 내림차순 정렬을 하고 싶다면, 반환 값에 -1을 곱해주면 됩니다.

2. Comparator 구현

Comparator도 유사합니다. 차이점은 구현의 대상이 되는 인자의 개수입니다. Comparable의 compareTo는 인자가 하나입니다. 즉, 자신과 입력받은 객체를 비교하는 메서드이고, Comparator의 compare는 입력받은 두 객체를 비교하는 메서드입니다.  따라서 Comparator는 비교대상이 자기 자신이 아니어도 되므로 별도로 구현이 가능합니다.

Comparable이 이미 구현되어있다면, Comparator를 따로 구현해서 다른 정렬 방식을 적용하는 것이 가능합니다.

import java.util.*;
public class User implements Comparator<User>{
    int no;
    String name;

    public User(int no, String name) {
        this.no = no;
        this.name = name;
    }

    @Override
    public int compare(User o1, User o2) {
        return o1.no - o2.no;
    }
}
import java.util.Comparator; //Comparator는 java.util.Comparator를 import 해야함

public class SortTest {

    public static void main(String[] args) {

        int[] num = {1, 6, 4, 2, 3, 5};
        char[] ch = {'B','D','E','C','A'};
        String[] str = {"Bbb","Bdd","Eee","Ccc","Aaa"};

        User[] userList = {
                new User(1,"Steve"),
                new User(5,"Tom"),
                new User(2,"Jane"),
                new User(4,"Henry"),
                new User(3,"Joker"),
        };

        Arrays.sort(userList,userList[0]); //Arrays.sort에 인자로 comparator를 넣어야 함

        for(User i:userList) System.out.println(i.no+" "+i.name);
    }
}

위 예에서 userList를 정렬하기 위해 Comparator를 넣을 때, userList[0]을 썼습니다. 즉, 아무 User 객체나 가져다 써도 무방합니다. 그러나, 일관성이 없어 보이네요.

그래서, User는 그대로 두고, 아래와 같이 익명내부클래스를 만들어서 객체를 사용합니다. (별도 클래스로 만들어도 무방합니다.)

public class User {
    int no;
    String name;

    public User(int no, String name) {
        this.no = no;
        this.name = name;
    }
}
import java.util.*;

public class SortTest {

    public static void main(String[] args) {

        int[] num = {1, 6, 4, 2, 3, 5};
        char[] ch = {'B', 'D', 'E', 'C', 'A'};
        String[] str = {"Bbb", "Bdd", "Eee", "Ccc", "Aaa"};

        User[] userList = {
                new User(1, "Steve"),
                new User(5, "Tom"),
                new User(2, "Jane"),
                new User(4, "Henry"),
                new User(3, "Joker"),
        };

		//익명클래스로 정의
        Comparator<User> comparator = new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.no - o2.no;
            }
        };

        Arrays.sort(userList, comparator);

        for (User i : userList) System.out.println(i.no + " " + i.name);
    }
}

 

참고 자료

https://st-lab.tistory.com/243

 

자바 [JAVA] - Comparable 과 Comparator의 이해

아마 이 글을 찾아 오신 분들 대개는 Comparable과 Comparator의 차이가 무엇인지 모르거나 궁금해서 찾아오셨을 것이다. 사실 알고보면 두 개는 그렇게 어렵지 않으나 아무래도 자바를 학습하면서 객

st-lab.tistory.com

https://www.daleseo.com/java-comparable-comparator/

 

[Java] 객체 정렬하기 1부 - Comparable vs Comparator

Engineering Blog by Dale Seo

www.daleseo.com

 

728x90

댓글