Programming/Java_자바

[JAVA 기초] Comparable 와 Comparator 인터페이스

LEFT 2022. 1. 17. 11:49

Explain


Compareble 인터페이스

: 컬렉션 프레임워크의 TreeSet, TreeMap 등 Tree--- 에서 쓰이는 인터페이스로, 정렬을 할 때 사용이 된다.
: 여기서 TreeSet, TreeMap은 객체의 정렬에 사용되는 클래스를 의미
: Compareble 인터페이스 compareTo()메서드를 구현하고, 매개변수와 객체 자신(this)를 비교한다는 점이다.

Comparator 인터페이스

: 컬렉션 프레임워크의 TreeSet, TreeMap 등 Tree--- 에서 쓰이는 인터페이스로, 정렬을 할 때 사용이 된다.
: Comparator 인터페이스는 compare()메서드를 구현하고, 두 개의 매개변수를 비교한다.

<TreeSet, TreeMap 클래스 특징>
- 중복을 허용하지 않으면서 오름차순이나 내림차순으로 객체를 정렬
- 내부적으로는 이진검색트리로 구현되어있음
- 이진 검색트리에 자료가 저장될때 비교항 저장될 위치를 정함
- 객체비교를 위해 Comparable 이나 Comparator 인터페이스를 구현해야함


Example

TreeSet 생성자에 Comparator가 구현된 객체를 매개변수로 전달해야하는 경우

TreeSet<Member> treeSet = new TreeSet<Member>(new Member());

 

일반적인 출력문으로 TreeSet, TreeMap을 출력하고자 한다면 Comparable의 compareTo() 메서드, Comparator 등이 구현되지 않아 오류가 발생할 수 있다.

테스트할 코드인 
Member.java에 구현이 되어야한다.
<Member.java>

// <중략>

	// Comparable 인터페이스의 메서드 구현
	@Override
	public int compareTo(Member member) { // Comparable 인터페이스를 상속받았으므로 compareTo 를 오버라이드 해줘야함 (재정의)
		// 데이터를 비교해야하므로 구현해야함
		// 이름순, Id순 둘다 가능
        
        // <Id순으로 정렬하는 방법>
        return (this.memberId - member.memberId);  // 나의 값이 더 큰 경우 (this.memberId) 양수가 반환되어 오름차순으로 정렬
												  // 음수가 반환되면 내림차순으로 정렬
												  // 반대로 나의 값이 커도 음수를 리턴시키고 싶으면 뒤에 *(-1); 을 추가해주면 된다.
		
		// <이름순으로 정렬하는 방법>
        // return (this.memberName.compareTo(member.memberName));
	}

	// Comparator 인터페이스의 메서드 구현
	@Override
	public int compare(Member member1, Member member2) { // 비교할 메서드를 구현, 여기서는 앞이 본인이고, 뒤의 member2가 비교할 값
		return member1.memberId - member2.memberId; // 오름차순 정렬
		// 일반적으로 CompareTo와 compare를 둘다 구현하지 않는다.
    
    }
	
	
}

위처럼 메서드를 재정의해준 후
테스트 코드에서 출력을 해보면
<ComparebleTest.java>

package chapter12_collection.treeset;

import java.util.TreeSet;

public class ComparebleTest {

	public static void main(String[] args) {
		TreeSet<String> tree = new TreeSet<String>(); // 예시를 위해 TreeSet의 정렬과정으로 실습
		
		tree.add("aaa");
		tree.add("ccc");
		tree.add("bbb");
		
		System.out.println(tree); // Collection 프레임워크의 클래스들은 모두 toString이 구현이 되어있으므로 tree로 주어도 무방
									// TreeSet 에는 정렬이 구현되어있기때문에 (Comparable 인터페이스 구현)
									// 순서는 aaa, ccc, bbb순으로 넣었지만
                                    // aaa, bbb, ccc 처럼 정렬이 되어 출력이되는 것을 확인 가능
	}

}

Result


<ComparatorTest.java>

package chapter12_collection.treeset;

import java.util.Comparator;
import java.util.TreeSet;

class MyCompare implements Comparator<String>{

	@Override
	public int compare(String str1, String str2) {
		
		return str1.compareTo(str2) * (-1); // 내림차순으로 반환
        									// 양수일 경우 +값이지만, -1을 곱해주어 음수로 출력
	}
	
	
}

public class ComparatorTest {

	public static void main(String[] args) {
		TreeSet<String> tree = new TreeSet<String>(new MyCompare()); // ()안에 new MyCompare처럼 구현하게되면 
        															// 비교하는방식은 위 구현된 클래스처럼 사용
		
		tree.add("aaa");
		tree.add("ccc");
		tree.add("bbb");
		
		System.out.println(tree); // 내림차순으로 정렬이되어 ccc, bbb, aaa가 출력됨
	}

}

Result

 


이처럼 Comparable 인터페이스Comparator 인터페이스를 비교 분석 할 수 있었습니다.

일반적으로는 Comparable 인터페이스를 더 많이 사용하지만,

Comparable이 이미 구현된 경우 둘 다 구현하고자 할 경우에는 다른 정렬방식으로 데이터를 처리할 수 있습니다.