본문 바로가기

프로그래밍/알고리즘

자바에서의 정렬

Sorting in Java


기본 타입 데이터의 정렬

- Arrays 클래스가 primitive 타입 데이터를 위한 메소드를 제공해준다.

int[] data = new int[capacity];

// data[0]에서 data[capacity - 1]까지 데이터가 꽉 차있을 경우

Arrays.sort(data);

//배열이 꽉 차지 않고 data[0]부터 data[size - 1]까지 차있을 경우

Arrays.sort(data, 0, size);

- int 이외 다른 primitive타입 데이터 (char, double 등)에 대해서도 같은 기능을 제공해준다.


객체의 정렬 - 문자열의 경우

- primitive타입 데이터들과 같이 Arrays.sort메소드를 통해 쉽게 정렬이 가능하다.

- 기본적으로 문자열은 String클래스 자체가 사전식 순서로 데이터간 크기를 정의하고 있기 때문이다.

Ex) String[] fruits = new String[] { "Pineapple", "Apple", "Orange", "Banana" };

Arrays.sort(fruits);

for (String name : fruits)

System.out.println(name);


객체의 정렬 - 사용자 정의 객체를 정렬할 때

public class Fruit {

public String name;

public int quantity;

public Fruit (String name, int quantity) {

this.name = name;

this.quantity = quantity;

}

}

//Fruit클래스 사용 시점

Fruit[] fruits = new Fruit[4];

fruits[0] = new Fruit("Pineapple", 70);

fruits[1] = new Fruit("Apple", 100);

fruits[2] = new Fruit("Orange", 80);

fruits[3] = new Fruit("Banana", 90);

Arrays.sort(fruits); //이 메소드가 어떤 자료형을 기준으로 하여 정렬을 하려는지 정확하지 않다는 문제가 있다.

-> 실제 실행을 한 결과 ClassCastException이 발생하게 된다.


객체의 정렬 - Comparable Interface

- 정확한 정렬 기준을 설정하지 않아 ClassCastException이 발생하게 될 때 사용할 수 있는 해결책 중 하나이다.

- Comparable Interface는 제너릭이고 자바API가 미리 정의해놓은 인터페이스이다.

- 단, 이 방식을 사용하게 된다면 compareTo메소드를 통해서는 여러 객체의 자료들 중 한 가지만을 선택하여 정렬을 수행해야 한다는 제한을 받게 된다.

- 여러 가지 기준들을 동시에 만족시키고 싶다면 Comparator를 사용하면 해결이 가능해진다.

public class Fruit implements Comparable<Fruit> {

public String name;

public int quantity;

public Fruit (String name, int quantity) {

this.name = name;

this.quantity = quantity;

}

public int compareTo(Fruit other) {

return name.compareTo(other.name);

}

}

//Fruit클래스 사용 시점

Fruit[] fruits = new Fruit[4];

fruits[0] = new Fruit("Pineapple", 70);

fruits[1] = new Fruit("Apple", 100);

fruits[2] = new Fruit("Orange", 80);

fruits[3] = new Fruit("Banana", 90);

Arrays.sort(fruits);

-> 위 코드를 실행하게 되면 문자열 기준으로 정렬을 수행해주게 된다.

이를 숫자 위주로 하고 싶다면 name이 아닌 quantity변수를 compareTo메소드에 넣어주면 된다.

public int compareTo(Fruit other) {

return quantity - other.quantity; // 음수면 상대가 더 큰 값, 양수면 상대가 더 작은 값이라는 뜻이다.

}


객체의 정렬 - Comparator

- Comparator 클래스를 상속받으며 compare 메소드를 오버라이딩하는 새로운 이름 없는 클래스를 정의한 뒤 그 클래스의 객체를 하나 생성하는 방식을 사용한다.

- 인터페이스라는 abstract 클래스의 객체를 생성하는것 같아 보여 말이 안되는 것 같아 보일 수 있다. 하지만 아래의 코드는 인터페이스를 implement하는 클래스를 만들어 그 객체를 생성하는 것이기 때문에 사용이 가능하다.

- 이러한 방식의 프로그래밍을 제너릭 프로그래밍이라고 한다.

//문자열 기준

//Fruit클래스 내에 static 멤버로 넣어놓는 것이 가장 깔끔하게 처리가 가능하다.

static Comparator<Fruit> nameComparator = new Comparator<Fruit>() { // anonymous class라고 불린다.

public int compare(Fruit fruit1, Fruit fruit2) {

return fruit1.name.compareTo(fruit2.name);

}

}; 

// 일련의 과정은 안에 Comparator인터페이스를 implement하는 클래스를 만드는데 그 이름은 없다는 의미를 가진다.

// 또한 인터페이스는 멤버 메소드를 반드시 구현해야 하기 때문에 중괄호를 통해 멤버 메소드를 구현하는 일까지

// 한 번에 수행하게 된다.

//숫자 기준

Comparator<Fruit> quantityComparator = new Comparator<Fruit>() {

public int compare(Fruit fruit1, Fruit fruit2) {

return fruit1.quantity - fruit2.quantity;

}

};

//name과 quantityComparator는 Comparator 인터페이스를 implement하는

//어떤 class의 객체 안에 들어있는 compare메소드를 요청한 것이다.

Arrays.sort(fruits, nameComparator); //static을 사용한 후에는 Arrays.sort(fruits, Fruit.nameComparator);

Arrays.sort(fruits, quantityComparator);


구현

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package Algorithm;
 
import java.util.Arrays;
import java.util.Comparator;
 
public class Grocery {
    public static void main(String[] args) {
        Fruit[] fruit = new Fruit[4];
        
        fruit[0= new Fruit("Pineapple"70);
        fruit[1= new Fruit("Apple"100);
        fruit[2= new Fruit("Orange"80);
        fruit[3= new Fruit("Banana"90);
        
        Arrays.sort(fruit, Fruit.nameComparator);
    }
}
 
class Fruit {
    String name;
    int quantity;
    
    public Fruit(String name, int quantity) {
        this.name = name;
        this.quantity = quantity;
    }
    
    public String toString() {
        return name + " | " + quantity;
    }
    
    static Comparator<Fruit> nameComparator = new Comparator<Fruit>() {
        public int compare(Fruit fruit1, Fruit fruit2) {
            return fruit1.name.compareTo(fruit2.name);
        }
    };
    
    static Comparator<Fruit> quantityComparator = new Comparator<Fruit>() {
        public int compare(Fruit fruit1, Fruit fruit2) {
            return fruit1.quantity - fruit2.quantity;
        }
    };
}
 
cs

ArrayList의 정렬 - 문자열

- Collections.sort 메소드를 통해 정렬을 수행한다.

Ex) List<String> fruits = new ArrayList<String>();

// 리스트에 객체 저장

fruits.add("Pineapple");

fruits.add("Apple");

fruits.add("Orange");

fruits.add("Banana");

Collections.sort(fruits);

for (String name : fruits)

System.out.println(name);

'프로그래밍 > 알고리즘' 카테고리의 다른 글

이진 검색 트리 (1)  (0) 2019.05.30
트리와 이진트리  (0) 2019.05.29
선형시간 정렬 알고리즘 (2)  (0) 2019.05.28
선형시간 정렬 알고리즘 (1)  (0) 2019.05.26
정렬의 하한점에 대해  (0) 2019.05.25