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 |