[0701] Java 배열 정렬 기능
1. 기본 자료형 배열 정렬
Java의 숫자형 기본 자료형(byte, char, int, long, float, double)의 배열은 Arrays 클래스의 sort 메소드를 사용하여 정렬할 수 있다.
public static void sort(byte[] a);
public static void sort(char[] a);
public static void sort(int[] a);
Arrays.sort(a);
2. 일부분만 정렬
Arrays 클래스의 sort 메소드
public static void sort(byte[] a, int fromIndex, int toIndex);
public static void sort(char[] a, int fromIndex, int toIndex);
public static void sort(int[] a, int fromIndex, int toIndex);
배열에서 fromIndex와 toIndex 사이의 항목만 정렬한다.
toIndex 위치는 포함하지 않음에 주의하자! ( fromIndex <= 인덱스 < toIndex )
Arrays.sort(a, 0, 5);
3. 객체 배열 정렬
◇ String[] 정렬
String[] a = { "zero", "one", "two", "three" };
Arrays.sort(a);
System.out.println(Arrays.toString(a));
◇ Integer[] 정렬
Integer[] a = { 17, 14, 11, 19 };
Arrays.sort(a);
System.out.println(Arrays.toString(a));
4. 사용자 정의 클래스 객체 배열 정렬
01) Comparable 인터페이스
Comparable 인터페이스를 구현한 클래스 객체의 배열은
Arrays 클래스의 sort 메소드를 사용하여 정렬할 수 있다.
◇ Comparable 인터페이스
interface Comparable<T> {
int compareTo(T obj)
}
Comparable 인터페이스는 compareTo 메소드를 포함한다.
compareTo 메소드는 this 객체와 파라미터 객체를 비교하여 this 객체가 크면 양의 정수를 리턴하고, this 객체가 작으면 음의 정수를 리턴하고, 두 객체의 값이 동일하면 0을 리턴한다.
* Comparable 인터페이스를 구현한 클래스
String, Date, Byte, Character, Integer, Long, Float, Double 등
https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html 참고
String 클래스, Integer 클래스도 Comparable 인터페이스를 구현했기 때문에 Arrays.sort 메소드로 정렬할 수 있다.
◇ 기본 자료형 배열과 객체 배열
- 기본 자료형 배열에는 기본 자료형 값이 저장된다.
- 참조형 배열에는 참조만 저장된다. 예를 들어 Integer 객체 배열에는 객체에 대한 참조만 저장된다.
- Java 언어에서 객체가 변수나 배열 안에 들어있을 수 없다.
- 변수나 배열에 들어있을 수 있는 것은 객체가 아니고 객체에 대한 참조이다.
- Java 언어에서 배열도 일종의 객체이다.
- 객체는 heap segment 영역에서 생성된다.
◇ Person 클래스 배열 정렬
Person 클래스가 Comparable 인터페이스를 구현하면 Arrays.sort 메소드를 사용하여 Person 객체 배열을 정렬할 수 있다.
public class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if ((obj instanceof Person) == false) return false;
Person p = (Person)obj;
return (this.name == null ? p.name == null : this.name.equals(p.name)) && this.age == p.age;
}
@Override
public String toString() {
return String.format("Person{name=\"%s\", age=%d}", name, age};
}
@Override
public int compareTo(Person p) {
int r = this.name.compareTo(p.name);
if(r != 0) return r;
return this.age - p.age; // 이름이 같다면 나이 비교 결과를 리턴
// 양수이면 파라미터 객체 - this 객체 오름차순으로
// 음수이면 this 객체 - 파라미터 객체
}
}
compareTo 메소드로 비교하여 정렬하면
먼저 이름 순서로 정렬되고, 이름이 동일한 경우에 나이 순서로 정렬될 것이다.
02) Comparator 인터페이스
◇ 순서 기준이 몇 개인가?
1. 순서 기준이 한 개인 경우
순서만을 비교하는 메소드를 그 객체에 구현하는 것이 좋다. Comparable 인터페이스를 구현하여 그 클래스에 CompareTo 메소드를 구현한다.
2. 순서 기준이 여러 개인 경우
각각의 비교 방법을 별도의 클래스로 구현하는 것이 좋다.
즉, Person 클래스에 비교 방법을 구현하는 것 보다 PersonNameComparator , PersonAgeComparator 등 비교 클래스를 따로 구현하는 것이 좋다. Comparable 인터페이스를 구현하여 compare 메소드를 구현해야 한다.
◇ Comparator 인터페이스
interface Comparator<T> {
int compare(T obj1, T obj2);
}
obj1 객체가 크면 양의 정수를 리턴, obj1 객체가 작으면 음의 정수를 리턴, 두 객체의 값이 동일하면 0을 리턴한다.
public class PersonNameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
int r= p1.name.compareTo(p2.name);
if(r != 0) return r;
return p1.age-p2.page;
}
}
public class PersonAgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
int r = p1.age - p2.page;
if(r != 0) return r;
return p1.name.compareTo(p2.name);
}
}
public class Example1 {
public static void main(String[] args) {
Person[] a = new Person[] {
new Person("홍길동", 18),
new Person("임꺽정", 22),
new Person("전우치", 23)
};
Arrays.sort(a, new PersonNameComparator());
System.out.println(Arrays.toString(a));
Arrays.sort(a, new PersonAgeComparator());
System.out.println(Arrays.toString(a));
}
}
5. List 배열 정렬
public static List sortByValue(final Map map) {
List<String> list = new ArrayList<>();
list.addAll(map.ketSet());
Collections.sort(list, new Comparator() {
public int compare(Object obj1, Object obj2) {
List<Integer> n1 = (List<Integer>)map.get(obj1);
List<Integer> n2 = (List<Integer>)map.get(obj2);
int r = n2.get(0)-n1.get(0);
if(r != 0) return r; // 승수가 같지 않다면
// 세트득실 비교
return n2.get(1) - n1.get(1);
}
};
return list;
}
Iterator<String> it = sortByValue(hashMap).iterator();
while(it.hasNext()) {
String key = it.next();
System.out.println(key+" "+hashMap.get(key).get(0));
}