09009
[Java] compareTo(), compare() 본문
객체를 정렬할 때 - Comparable 인터페이스
[Java] Arrays 클래스
Arrays 클래스 • 배열 조작 기능을 하는 클래스 • 배열을 다루는데 유용한 메서드가 정의되어 있다. 배열의 비교와 출력 - equals(), toString() • equals() 두 배열에 저장된 모든 요소를 비교하여 같으
haaland09009.tistory.com
위의 게시글에서 확인할 수 있듯이 Arrays.sort()를 호출만 하면 컴퓨터가 알아서 배열을 정렬하는 것처럼 보이지만
사실은 Character 클래스의 Comparable의 구현에 의해 정렬된 것이다.
Comparator와 Comparable은 모두 인터페이스로 컬렉션을 정렬하는 데 필요한 메서드를 정의한다.
- Comparator와 Comparable의 실제 소스
public interface Comparator {
int compare(Object o1, Object o2);
boolean equals(Object obj);
}
public interface Comparable {
public int compareTo(Object o);
}
Comparable : 기존 정렬기준을 구현하는데 사용. Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있다.
Comparator : 내림차순으로 정렬하던지 아니면 다른 기준에 의해 정렬하고 싶을 경우 Comparator를 구현
• 정렬의 기준을 정하는 인터페이스
Java에서 기본 자료형은 부등호를 통해서 서로 쉽게 비교할 수 있다.
int x = 3, y = 2;
System.out.println(x > y); // true
System.out.println(x == y); // false
System.out.println(x < y); //false
사람의 이름과 나이 정보를 갖고 있는 클래스가 있다고 가정해 보자.
이러한 클래스의 경우 부등호를 통해 크고 작음을 비교할 수 있을까?
이와 같은 클래스는 이름의 대소를 비교할 것인지, 나이의 대소를 비교할 것인지
즉, 비교 기준이 명확하게 정해져 있지 않기 때문에 정확한 비교를 할 수 없다.
그래서 우리는 Comparable 또는 Comparator 인터페이스를 이용하여 비교 기준을 직접 정한 후 객체를 비교할 수 있게 하여야 한다.
• CompareTo() 메서드
- Comparable 인터페이스에 정의된 메서드 중 하나
- 두 개의 값, 객체를 비교하여 int값으로 반환하는 함수
- 숫자 비교: 크다(1), 같다(0), 작다(-1)와 같은 결괏값 반환
- 문자열 비교:같다(0), 그 외 양수/음수값과 같은 결과를 반환
• a.compareTo(b) 메서드
- a와 b가 같은 순서면 0
- a > b 이면 0보다 큰 값 반환
- a < b 이면 0보다 작은 값 반환
위 메서드를 수행하고 결과 값이 0이면 같은 순서. 0보다 크면 a > b, 0보다 작으면 b > a로 순서가 정해진다.
새 클래스를 만들고 그 클래스의 객체들 사이에 순서를 정해주고 싶다면
Comparable 인터페이스를 구현하고 compareTo 메서드를 위 규칙대로 정의하여 순서를 정해줄 수 있다.
!!! Comparable은 인터페이스이므로 Comparable을 이용하여 객체를 정렬하려면 비교하고자 하는 객체에서
아래에 작성된 소스코드와 같이 Comparable 인터페이스를 구현해야 한다.!!!
✍ Member1.java
package ch11;
// 객체를 정렬하기 위해서는 comparable 을 구현해야 한다.
public class Member1 implements Comparable<Member1> {
String name;
public Member1(String name) {
this.name = name;
}
// 정렬할 기준을 재정의한다.
@Override
public int compareTo(Member1 o) {
return name.compareTo(o.name);
}
@Override
public String toString() {
return name;
}
}
✍ Arrays4.java
package ch11;
import java.util.Arrays;
public class Arrays4 {
public static void main(String[] args) {
Member1 m1 = new Member1("음바페");
Member1 m2 = new Member1("홀란드");
Member1 m3 = new Member1("케인");
Member1 m4 = new Member1("비니시우스");
Member1[] members = {m1, m2, m3, m4};
Arrays.sort(members);
System.out.println(Arrays.toString(members));
int index = Arrays.binarySearch(members, m2);
System.out.println("찾은 인덱스 : " + index);
}
}
💻 출력
[비니시우스, 음바페, 케인, 홀란드]
찾은 인덱스 : 3
예제
• 나이를 기준으로 정렬하고 싶을 때
✍ Member2.java
package ch11;
public class Member2 implements Comparable<Member2>{
String name;
int age;
public Member2(String name, int age) {
this.name = name; this.age =age;
}
// 비교하는 기준
@Override
public int compareTo(Member2 o) {
// 비교 대상은 문자열이어야 한다.
String age1 = age + ""; // 숫자 + 문자 = 문자
String age2 = o.age + "";
return age1.compareTo(age2);
}
// @Override
// public int compareTo(Member2 o) {
// if (age > o.age) return 1;
// else if (age < o.age) return -1;
// else return 0;
// }
@Override
public String toString() {
return name + "(" + age + ")";
}
}
✍ ArraysMember2.java
package ch11;
import java.util.Arrays;
import java.util.Collections;
public class ArraysMember2 {
public static void main(String[] args) {
Member2 m1 = new Member2("손흥민", 32);
Member2 m2 = new Member2("이강인", 23);
Member2 m3 = new Member2("백승호", 27);
Member2 m4 = new Member2("김민재", 28);
Member2 m5 = new Member2("김영권", 34);
Member2[] members = {m1, m2, m3, m4, m5};
System.out.println(Arrays.toString(members)); // [손흥민(32), 이강인(23), 백승호(27), 김민재(28), 김영권(34)]
// 나이를 기준으로 오름차순 정렬
Arrays.sort(members);
System.out.println(Arrays.toString(members)); // [이강인(23), 백승호(27), 김민재(28), 손흥민(32), 김영권(34)]
// 나이를 기준으로 내림차순 정렬
Arrays.sort(members, Collections.reverseOrder());
System.out.println(Arrays.toString(members)); // [김영권(34), 손흥민(32), 김민재(28), 백승호(27), 이강인(23)]
}
}
Member2.java에 있는 compareTo() 메서드에서 나이를 기준으로 비교하도록 설정하였으므로 ArraysMember2.java에 있는 main 메서드 실행 결과 나이를 기준으로 정렬된 것을 확인할 수 있다.
그렇다면 이름으로 비교하면 어떤 결과가 나올까?
• 이름을 기준으로 정렬하고 싶을 때
✍ Member2.java
package ch11;
public class Member2 implements Comparable<Member2>{
String name;
int age;
public Member2(String name, int age) {
this.name = name; this.age =age;
}
// 비교하는 기준
@Override
public int compareTo(Member2 o) {
return name.compareTo(o.name);
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
✍ ArraysMember2.java
package ch11;
import java.util.Arrays;
import java.util.Collections;
public class ArraysMember2 {
public static void main(String[] args) {
Member2 m1 = new Member2("손흥민", 32);
Member2 m2 = new Member2("이강인", 23);
Member2 m3 = new Member2("백승호", 27);
Member2 m4 = new Member2("김민재", 28);
Member2 m5 = new Member2("김영권", 34);
Member2[] members = {m1, m2, m3, m4, m5};
System.out.println(Arrays.toString(members)); // [손흥민(32), 이강인(23), 백승호(27), 김민재(28), 김영권(34)]
// 이름을 기준으로 오름차순 정렬
Arrays.sort(members);
System.out.println(Arrays.toString(members)); //[김민재(28), 김영권(34), 백승호(27), 손흥민(32), 이강인(23)]
// 이름을 기준으로 내림차순 정렬
Arrays.sort(members, Collections.reverseOrder());
System.out.println(Arrays.toString(members)); //[이강인(23), 손흥민(32), 백승호(27), 김영권(34), 김민재(28)]
}
}
Member2.java에 있는 compareTo() 메서드에서 이름을 기준으로 비교하도록 설정하였으므로 ArraysMember2.java에 있는 main 메서드 실행 결과 이름을 기준으로 제대로 정렬된 것을 확인할 수 있다.
우리는 이전에 사람의 이름과 나이 정보를 갖고 있는 클래스의 대소비교를 어떻게 할 것인지에 대한 의문이 있었다. 위의 소스코드에서 볼 수 있듯이 comparable 인터페이스를 이용하면 비교 기준을 직접 정하여 우리가 원하는 대로 비교할 수 있음을 확인하였다.
예제
나이를 기준으로 정렬하기
✍ 입력
import java.util.Iterator;
import java.util.TreeSet;
class Person implements Comparable<Person> {
String name; int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void showData() {
System.out.printf("%s %d\n", name, age);
}
@Override
public int compareTo(Person p) { // a.compareTo(b)
if (age > p.age) return 1;
else if (age < p.age) return -1;
else return 0;
}
}
public class ComparablePerson {
public static void main(String[] args) {
TreeSet<Person> sTree = new TreeSet<Person>();
sTree.add(new Person("Choi", 24));
sTree.add(new Person("Hong", 29));
sTree.add(new Person("Lee", 21));
Iterator<Person> itr = sTree.iterator();
while(itr.hasNext())
itr.next().showData();
}
}
💻 출력
Lee 21
Choi 24
Hong 29
나이가 같다면 이름을 기준으로 정렬하기
✍ 입력
import java.util.Iterator;
import java.util.TreeSet;
class Person implements Comparable<Person> {
String name; int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void showData() {
System.out.printf("%s %d\n", name, age);
}
@Override
public int compareTo(Person p) {
// a.compareTo(b) 메서드 수행의 결과 값이 0이면 같은 순서. 0보다 크면 a > b, 0보다 작으면 b > a로 순서가 정해짐
// 새 클래스를 만들고 그 클래스의 객체들 사이에 순서를 정해주고 싶다면
// Comparable 인터페이스를 구현하고 compareTo 메서드를 위 규칙대로 정의하여 순서를 정해줄 수 있다.
if (age > p.age) return 1; // 나이가 크면 뒷 순서
else if (age < p.age) return -1; // 나이가 작으면 앞 순서
else {
return name.compareTo(p.name); // 나이가 같다면 이름의 사전순대로 순서를 정함.
// String 클래스는 사전 순대로 크기가 정해지도록 이미 compareTo 메서드를 오버라이딩 해놨다.
}
}
}
public class ComparablePerson {
public static void main(String[] args) {
TreeSet<Person> sTree = new TreeSet<Person>();
sTree.add(new Person("Lee", 21));
sTree.add(new Person("Hong", 21));
sTree.add(new Person("Choi", 21));
sTree.add(new Person("Lee", 22));
sTree.add(new Person("Hong", 22));
sTree.add(new Person("Choi", 22));
Iterator<Person> itr = sTree.iterator();
while(itr.hasNext())
itr.next().showData();
}
}
💻 출력
Choi 21
Hong 21
Lee 21
Choi 22
Hong 22
Lee 22
객체를 정렬할 때 - Comparator 인터페이스
String 클래스에서 순서를 임의로 정하고 싶을 때 - Comparator
사전 순이 아닌 문자열의 길이를 기준으로 정렬할 때
✍ 입력
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
class StrLenComparator implements Comparator<String> {
public int compare(String str1, String str2) {
if (str1.length() > str2.length()) return 1;
else if (str1.length() < str2.length())
return -1;
else return 0;
}
}
public class IntroComparator {
public static void main(String[] args) {
TreeSet<String> tSet = new TreeSet<String>(new StrLenComparator());
tSet.add("Orange"); tSet.add("Apple");
tSet.add("Dog"); tSet.add("Individual");
Iterator<String> itr = tSet.iterator();
while(itr.hasNext())
System.out.println(itr.next());
}
}
💻 출력
Dog
Apple
Orange
Individual
Comparator 인터페이스를 구현하여 compare 메서드를 문자열의 길이를 기준으로 정렬하는 의미로 재정의하였기 때문에 위와 같은 결과가 출력된다.
'Back-End > JAVA' 카테고리의 다른 글
[Java] 고객 관리 (1) - Intellij와 DB 연동, 클래스 생성 (0) | 2023.04.16 |
---|---|
[Java] Intellij에서 파일 내 해당 텍스트 일괄 변경하는 방법 (0) | 2023.04.07 |
[Java] 문자열(String) 비교 : equals()와 == 의 차이점, String 클래스 (6) | 2023.04.06 |
[Java 주요 문제 풀이 (1)] - 배열, 생성자, 메서드 (0) | 2023.04.06 |
[Java] StringTokenizer (0) | 2023.04.06 |