Comparable
... 와 비교되는
이라는 의미이다.
Comparable은 자바의 인터페이스이다.
인터페이스 내에 선언된 메서드는 반드시 구현해야 한다.
선언만 한 체 구현하지 않는다면, 에러가 날것이다.
이 인터페이스는 객체가 natural order(자연적 순서)를
가지도록 하기 위해 사용된다.
natural order는 무엇일까?
자연의 질서대로 오름차순으로 놓이는 것이다.
예시
문자열 정렬 | 자연 정렬 | |
book1 | book1 | |
book10 | book2 | |
book100 | book10 | |
book2 | book21 | |
book21 | book100 |
내용 참고 - 제타위키 -
수정자 및 타입 | 메서드 설명 |
int | compareTo(T o) 순서에 따라 이 개체를 지정한 개체와 비교 sgn(x.compareTo(y)) == - sgn(y.compareTo(x))가 보장되어야 한다. => x를 y와 비교할때의 부호와 y를 x와 비교할때의 부호 상관 관계가 같아야한다. ex) x = 11 , y = 12 x.comparTo(y) == 11과 12를 비교했을 때 x(이 개체)가 y(지정한 개체) 보다 작으므로 음의 정수 -1를 반환 y.comparTo(y) == 12와 11을 비교 했을 때 y(이 개체)가 x(지정한 개체) 보다 크므로 양의 정수 1 을 반환 따라서 sgn( -1 == - (1) ) 은 보장된다. x.compareTo(y) > 0 && y.compareTo(z) > 0 만으로 x.compareTo(z) > 0 을 암시 할 수 있어야 한다. ex) x를 y와 비교할때의 반환 값(x>y 반환 1)과 y를 z와 비교할때의 반환값(y>z 반환 1)이 둘다 양수를 만족하면 (x>z 반환 1)이 되는 것을 알 수 있어야 한다. => x>y , y>z => x>y>z 따라서 x>z는 자동적으로 알 수 있다. 마지막으로, 구현자는 x.compareTo(y) == 0이 모든 z에 대하여 sgn(x.compareTo(z)) == sgn(y.compareTo(z))을 암시하는지 확인해야 한다. ex) x = y 라면 명시하지 않더라도 x와 z의 비교 관계와 y와 z의 비교 관계가 같음을 알 수 있어야한다. x = y = 2, z = 1 일때 x > z 만 봐도 y > z 임을 알 수 있다. (x.compareTo(y) == 0) == (x.equals(y))로 하는 것을 강력히 추천하지만 무조건 요구하는 것은 아니다. ⭐sgn(sign(um) function) 는 특수함수중 하나로, 어떤 실수의 부호를 출력하는 함수이다. 이 함수에서는 음수, 0, 양수인지에 따라 -1, 0, 1 중 하나를 반환하도록 정의된다. 참고 - 나무위키 - Parameters : 비교할 개체 Returns : 이 개체가 지정한 개체보다 작을 때 음의 정수, 이 개체가 지정한 개체보다 같을 때 0, 이 개체가 지정한 개체보다 클 때 양의 정수를 반환 Throws : NullPointerException : 지정한 개체가 null인 경우 ClassCastException : 지정한 개체의 형식으로 인해 이 개체와 비교할 수 없을 때 |
최대한 이해하기 쉽도록 예제를 풀어 설명해 보았다.
천천히 읽으면 이해는 될것이다.
그래도 어려우니
한번 예제를 만들어서 직접 사용해 보면
이렇게 사용하는 구나 정도는
익힐 수 있다.
Book 클래스
public class Book implements Comparable<Book> {
private String title;
private String author;
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
//title에 따른 자연적 정렬
@Override
public int compareTo(Book other) {
System.out.println(this.title + " 와 " + other.title + " 비교");
System.out.println("비교 결과 : " +this.title +" " + this.title.compareTo(other.title));
return this.title.compareTo(other.title);
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", author='" + author + '\'' +
'}';
}
}
Book클래스를 만들어 Comparable 인터페이스를 구현해 보았다.
인터페이스구현 시
인터페이스 내부함수는 오버라이드를 하여
반드시 구현해주어야 한다.
compareTo()메서드를 오버라이드하여
title을 기준으로 정의하도록 구현하였다.
compareTo() 메서드의 반환값은 정수형(int)이다.
또한 쉽게 확인하기 위해 print문을 추가해 주었고,
toString메서드를 오버라이드해 주었다.
위의 예제는 책의 제목에 따른
natural order(자연스러운 정렬)을 해주었다.
이제 클래스를 사용해서 확인해보자!
Main 클래스
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Book> bookList = new ArrayList<>();
bookList.add(new Book("위대한 게츠비", "F. Scott Fitzgerald"));
bookList.add(new Book("파이 이야기", "Yann Martel"));
bookList.add(new Book("안나라수마나라1", "하일권"));
bookList.add(new Book("안나라수마나라2", "하일권"));
bookList.add(new Book("안나라수마나라3", "하일권"));
bookList.add(new Book("MOOMIN 혜성이 다가온다", "Tove Jasson"));
bookList.add(new Book("1234 당근이 이거뿐이네?", "오지랖 토끼"));
Collections.sort(bookList);
//출력
System.out.println(bookList);
}
}
--------------------------------------------------------------------------------------
파이 이야기 와 위대한 게츠비 비교
비교 결과 : 파이 이야기 3080
안나라수마나라1 와 파이 이야기 비교
비교 결과 : 안나라수마나라1 -3524
안나라수마나라1 와 파이 이야기 비교
비교 결과 : 안나라수마나라1 -3524
안나라수마나라1 와 위대한 게츠비 비교
비교 결과 : 안나라수마나라1 -444
안나라수마나라2 와 위대한 게츠비 비교
비교 결과 : 안나라수마나라2 -444
안나라수마나라2 와 안나라수마나라1 비교
비교 결과 : 안나라수마나라2 1
안나라수마나라3 와 위대한 게츠비 비교
비교 결과 : 안나라수마나라3 -444
안나라수마나라3 와 안나라수마나라2 비교
비교 결과 : 안나라수마나라3 1
MOOMIN 혜성이 다가온다 와 안나라수마나라3 비교
비교 결과 : MOOMIN 혜성이 다가온다 -50427
MOOMIN 혜성이 다가온다 와 안나라수마나라2 비교
비교 결과 : MOOMIN 혜성이 다가온다 -50427
MOOMIN 혜성이 다가온다 와 안나라수마나라1 비교
비교 결과 : MOOMIN 혜성이 다가온다 -50427
1234 당근이 이거뿐이네? 와 안나라수마나라3 비교
비교 결과 : 1234 당근이 이거뿐이네? -50455
1234 당근이 이거뿐이네? 와 안나라수마나라1 비교
비교 결과 : 1234 당근이 이거뿐이네? -50455
1234 당근이 이거뿐이네? 와 MOOMIN 혜성이 다가온다 비교
비교 결과 : 1234 당근이 이거뿐이네? -28
[Book{title='1234 당근이 이거뿐이네?', author='오지랖 토끼'},
Book{title='MOOMIN 혜성이 다가온다', author='Tove Jasson'},
Book{title='안나라수마나라1', author='하일권'},
Book{title='안나라수마나라2', author='하일권'},
Book{title='안나라수마나라3', author='하일권'},
Book{title='위대한 게츠비', author='F. Scott Fitzgerald'},
Book{title='파이 이야기', author='Yann Martel'}]
Process finished with exit code 0
조금 편하게 보기위해 임의로 리스트출력은 개행을 해주었다.
출력결과의 숫자에 대하여 정확한 수치의 의미는 모르겠지만
자기들 끼리 비교하며 정수로 연산되어 비교됨을 알 수 있다.
결과적으로
책의 제목에 대한 natural order가 적용되어
list는 숫자 오름차순 > 영어오름차순 > 한글오름차순
list를 사용하였기 때문에
collections.sort()통해
정렬된것을 확인 할 수 있다.
다른 예제로 한 번 더 해보았다.
Person 클래스
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
//이객체 - 비교할 객체가 차이에 따라 서로 비교
@Override
public int compareTo(Person other) {
System.out.println(this.age + " - " + other.age +":" + (this.age - other.age));
return this.age - other.age;
}
}
compareTo()연산 과정을 보기 위해
print문을 넣어 주었다.
Main 클래스
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
//Person타입 배열 선언
Person[] people = new Person[3];
people[0] = new Person("John", 30);
people[1] = new Person("Jane", 25);
people[2] = new Person("Alice", 35);
//클래스의 인터페이스로 구현된 정렬 순서에 따라 정렬
Arrays.sort(people);
for (Person person : people) {
System.out.println(person.getName() + " " + person.getAge());
}
}
}
----------------------------------------------------------------------------
25 - 30:-5
35 - 25:10
35 - 30:5
Jane 25
John 30
Alice 35
Process finished with exit code 0
Arrays.sort()를 통해
위의 출력을 통해 어떻게 비교되어
정렬이 되는지 파악할 수 있다.
'자바 탐구' 카테고리의 다른 글
Intellij) 테마 바꾸기 (0) | 2023.04.03 |
---|---|
인터페이스) Comparator (0) | 2023.03.21 |
자료구조) 큐 (0) | 2023.03.13 |
자료구조) 우선순위 큐 (0) | 2023.03.13 |
자료구조) 스택 (0) | 2023.03.12 |