Java

[고급자바] 정렬(Comparator, Comparable)

elog 2023. 3. 3. 00:00

1. Comparator(외부 정렬)

- 외부에 별도로 정렬 기준을 구현하고 싶을 때 구현하는 인터페이스.

- compare() 메서드 재정의

 

A. 외부 정렬 기준 클래스(Comparator)

compare() 메서드

- 0 : 두 값이 같다.

- 양수 : 앞, 뒤의 순서를 바꾼다.

- 음수 : 앞, 뒤의 순서를 바꾸지 않는다.

 

1) 오름차순

- 앞의 값이 크면 양수, 같으면 0, 앞의 값이 작으면 음수

 

2) 내림차순

- 앞의 값이 크면 음수, 같으면 0, 앞의 값이 작으면 양수

class Desc implements Comparator<String>{
	@Override
	public int compare(String str1, String str2) {
		// 내림차순
		if (str1.compareTo(str2) > 0) {
			return -1;
		} else if (str1.compareTo(str2) < 0) {
			return 1;
		} else {
			return 0;
		}
	}
}
ArrayList<String> list = new ArrayList<>();

list.add("일지매");
list.add("홍길동");
list.add("성춘향");
list.add("변학도");
list.add("이순신");		
System.out.println("정렬전 : " + list);

Collections.sort(list);
System.out.println("정렬후 : " + list);

Collections.shuffle(list);	// 자료 섞기
System.out.println("자료 섞기 후 : " + list);

// 외부 정렬 기준을 적용해서 정렬하기
Collections.sort(list, new Desc());
System.out.println("내림차순 정렬후 : " + list);

 

B. 전체 코드

public class ListSortTest {
	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
		
		list.add("일지매");
		list.add("홍길동");
		list.add("성춘향");
		list.add("변학도");
		list.add("이순신");
		System.out.println("정렬전 : " + list);
        
		Collections.sort(list);
		System.out.println("정렬후 : " + list);
		
		Collections.shuffle(list);	// 자료 섞기
		System.out.println("자료 섞기 후 : " + list);
		
		
		// 외부 정렬 기준
		Collections.sort(list, new Desc());
		System.out.println("내림차순 정렬후 : " + list);
	}
}

class Desc implements Comparator<String>{
	@Override
	public int compare(String str1, String str2) {
		// 내림차순
		if (str1.compareTo(str2) > 0) {
			return -1;
		} else if (str1.compareTo(str2) < 0) {
			return 1;
		} else {
			return 0;
		}
	}
}

2. Comparable(내부 정렬)

- Collection에 추가되는 데이터 자체에 정렬 기준을 넣고 싶을 때 구현하는 인터페이스.

- compareTo() 메서드 재정의

- String 클래스, Wrapper 클래스, Date 클래스, File 클래스에는 내부 정렬 기준이 구현되어 있다.

- 내부 정렬 기준은 오름차순으로 처리되도록 구현되어 있다.

 

A. 내부 정렬 기준 클래스(Comparable)

class Member implements Comparable<Member> {
	private int num;	// 회원번호
	private String name;	// 회원이름
	private String tel;	// 전화번호
	
	// 생성자
	public Member(int num, String name, String tel) {
		super();
		this.num = num;
		this.name = name;
		this.tel = tel;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	@Override
	public String toString() {
		return "Member [num=" + num + ", name=" + name + ", tel=" + tel + "]";
	}

	@Override
	public int compareTo(Member mem) {
		// 회원이름의 오름차순
		return this.getName().compareTo(mem.getName());
	}

}
ArrayList<Member> memList = new ArrayList<>();
		
memList.add(new Member(1, "홍길동", "010-1111-1111"));
memList.add(new Member(2, "이순신", "010-2222-1111"));
memList.add(new Member(9, "성춘향", "010-3333-1111"));
memList.add(new Member(3, "강감찬", "010-4444-1111"));
memList.add(new Member(6, "일지매", "010-5555-1111"));
memList.add(new Member(2, "변학도", "010-6666-1111"));

System.out.println("정렬전");
for (Member mem : memList) {
	System.out.println(mem);
}

Collections.sort(memList);

System.out.println("정렬 후");
for (Member mem : memList) {
	System.out.println(mem);
}

 

B. 전체 코드

package kr.or.ddit.basic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class ListSortTest02 {

	public static void main(String[] args) {
		ArrayList<Member> memList = new ArrayList<>();
		
		memList.add(new Member(1, "홍길동", "010-1111-1111"));
		memList.add(new Member(2, "이순신", "010-2222-1111"));
		memList.add(new Member(9, "성춘향", "010-3333-1111"));
		memList.add(new Member(3, "강감찬", "010-4444-1111"));
		memList.add(new Member(6, "일지매", "010-5555-1111"));
		memList.add(new Member(2, "변학도", "010-6666-1111"));
		
		System.out.println("정렬전");
		for (Member mem : memList) {
			System.out.println(mem);
		}
		System.out.println("--------------------------------------------------");
		
		Collections.sort(memList);
		System.out.println("정렬 후");
		for (Member mem : memList) {
			System.out.println(mem);
		}
	}
}

class Member implements Comparable<Member> {
	private int num;		// 회원번호
	private String name;	// 회원이름
	private String tel;		// 전화번호
	
	// 생성자
	public Member(int num, String name, String tel) {
		super();
		this.num = num;
		this.name = name;
		this.tel = tel;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	@Override
	public String toString() {
		return "Member [num=" + num + ", name=" + name + ", tel=" + tel + "]";
	}

	@Override
	public int compareTo(Member mem) {
		// 회원이름의 오름차순
		return this.getName().compareTo(mem.getName());
	}
}

 

+ 외부 정렬 클래스

// Member의 회원번호(num)의 내림차순으로 정렬하는 외부 정렬 기준 클래스
class SortNumDesc implements Comparator<Member> {	
	@Override
	public int compare(Member mem1, Member mem2) {
//		방법1
		if (mem1.getNum() > mem2.getNum()) {
			return -1;	// mem1.getNum이 크면 내림차순 >> 변경X
		} else if (mem1.getNum() < mem2.getNum()) {
			return 1;	// mem1.getNum이 작으면 오름차순 >> 변경O
		} return 0;
	}
}

//		방법2
//		return mem2.getNum() - mem1.getNum();	// 양수일 경우에만 가능하다.
		
//		방법3
		// Wrapper 클래스를 이용하는 방법1
		// 오름차순의 경우 * -1를 빼면 된다.
//		return new Integer(mem1.getNum()).compareTo(mem2.getNum()) * 1;
		
//		방법4
		// Wrapper 클래스를 이용하는 방법2
//		return Integer.compare(mem1.getNum(), mem2.getNum()) * -1;
	}
}
Collections.sort(memList, new SortNumDesc());

System.out.println("회원번호의 내림차순 정렬 후");
for (Member mem : memList) {
	System.out.println(mem);
}