Programming/Java

[0701] Java 배열 정렬 기능

jihyun03 2020. 7. 1. 16:02

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));
}