[Java] 8. 제네릭-`Comparable` 와 `Comparator` 인터페이스(feat. Collections sort())
제네릭 포스팅의 연장선으로 Comparable<T>
와 Comparator<T>
인터페이스를 구현하여 java 정렬 방법으로 java.util.Collections 클래스의 sort()를 이용한 정렬 포스팅이다.
해당 포스팅에는 이 외에 LocalDate 비교와 Ramdom 메서드 짧은 예제 코드도 포함하고 있다.
1. Collections.sort()
제네릭 포스팅의 연장선으로 Comparable<T>
와 Comparator<T>
인터페이스를 구현하여 java 정렬 방법으로 java.util.Collections 클래스의 static 메소드인 sort()를 이용해 정렬을 한다.
List<User> userList = getUserList();
Collections.sort(userList);
아래 Collections 클래스의 sort() 메서드를 보면 타입이나 메서드에서 <? super T>
제네릭 와일드 카드의 하한 제한으로 T와 그 조상들만 가능하게 제한을 두고 있다.
Collections 클래스 sort()
Modifier and Type | Method |
---|---|
static <T extends Comparable<? super T>> void | sort(List<T> list) |
static <T> void | sort(List<T> list, Comparator<? super T> c) |
2. Comparable<T>
와 Comparator<T>
인터페이스
Collections 의 sort() 메서드를 통해 특정 필드를 사용자정의로 정렬을 하려면
아래 표에 Comparable<T>
와 Comparator<T>
인터페이스를 이용해서
메서드를 오버라이드헤서 구현하면 된다.
Comparable<T> 와 Comparator<T> 간단비교
Comparable<T>
Comparator<T>
Package java.lang java.util Method compareTo(T o) compare(Object o1, Object o2) 비교대상 자기자신 두 객체
아래는 사용방법에 대한 스케치(?) 코드이다.
더 밑에는 전체 예제 코드와 주석이 있으며, 해당 포스팅 내용은 이걸로 끝이다.
1) Comparable<T> 인터페이스의 compareTo()
오버라이드
static <T extends Comparable<? super T>> void
List<User> userList = getUserList();
Collections.sort(userList);
@Override
public int compareTo(User u) {
//a > b : 양수를 반환
//a < b : 음수를 반환
//a == b : 0을 반환
return 구현;
}
2) 인터페이스의 compare()
오버라이드
static <T> void
List<User> userList = getUserList();
Collections.sort(userList, new User());
@Override
public int compare(User u1, User u2) {
//a > b : 양수를 반환
//a < b : 음수를 반환
//a == b : 0을 반환
return 구현;
}
3. 전체 예제 코드
해당 예제코드는 추가로 LocalDate 비교와 Ramdom 메서드 짧은 예제 코드도 포함하고 있다.
class User implements Comparable<User>, Comparator<User> {
private int id;
private String name;
private int point;
private LocalDate joinDt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
public LocalDate getJoinDt() {
return joinDt;
}
public void setJoinDt(LocalDate joinDt) {
this.joinDt = joinDt;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", point=" + point +
", joinDt=" + joinDt +
"}\n";
}
//Comparable 인터페이스의 compareTo 오버라이드
@Override
public int compareTo(User u) {
//a > b : 양수를 반환
//a < b : 음수를 반환
//a == b : 0을 반환
if (this.point > u.point) return 1;
else if (this.point < u.point) return -1;
else return 0;
}
//Comparator 인터페이스의 compare 오버라이드
@Override
public int compare(User u1, User u2) {
LocalDate u1JoinDt = u1.getJoinDt();
LocalDate u2JoinDt = u2.getJoinDt();
//compareTo ReturnValue
//a > b : 양수를 반환
//a < b : 음수를 반환
//a == b : 0을 반환
return u1JoinDt.compareTo(u2JoinDt);
}
//내부클래스로 Comparator 인터페이스의 compare 오버라이드
static class UserIdOrderByDesc implements Comparator<User> {
@Override
public int compare(User u1, User u2) {
//a > b : 양수를 반환
//a < b : 음수를 반환
//a == b : 0을 반환
if (u1.getId() > u2.getId()) return 1;
else if (u1.getId() < u2.getId()) return -1;
else return 0;
}
}
}
public class ExGenericCollections {
public static void main(String... args) {
List<User> userList = getUserList();
//Point 로 Comparable 이용한 정렬
Collections.sort(userList);
System.out.println(userList);
//JoinDt 로 Comparator 이용한 정렬
Collections.sort(userList, new User());
System.out.println(userList);
//Id 로 내부클래스의 Comparator 이용한 정렬
Collections.sort(userList, new User.UserIdOrderByDesc());
System.out.println(userList);
}
public static List<User> getUserList() {
List<User> userList = new ArrayList<User>();
User user = new User();
for (int i = 0; i<20; i++) {
user = new User();
user.setId( getRandomUserId() );
user.setName( getRandomName() );
user.setPoint( getRandomPoint() );
user.setJoinDt( getRandomJoinDt() );
userList.add( user );
}
return userList;
};
public static int getRandomUserId() {
return new Random().nextInt(10000);
}
public static int getRandomPoint() {
int min = 1000;
return new Random().nextInt(1000) + min;
}
public static String getRandomName() {
return getName();
};
public static LocalDate getRandomJoinDt(){
Random r = new Random();
return LocalDate.of(r.nextInt(20) + 2000, r.nextInt(11) + 1, r.nextInt(28) + 1);
}
public static String getName() {
String[] firstNameArr = {
"김"
, "이"
, "박"
, "최"
, "정"
, "안"
, "강"
};
String[] lastNameArr = {
"민준"
, "서준"
, "도윤"
, "예준"
, "시우"
, "하준"
, "주원"
, "지호"
, "지후"
, "준우"
, "준서"
, "건우"
, "도현"
, "현우"
, "서연"
, "서윤"
, "지우"
, "서현"
, "하은"
, "하윤"
, "민서"
, "지유"
, "윤서"
, "지민"
, "채원"
, "수아"
, "지아"
, "지윤"
, "은서"
};
int r1 = new Random().nextInt(7);
int r2 = new Random().nextInt(30);
String n1 = firstNameArr[r1];
String n2 = lastNameArr[r1];
return n1 + n2;
}
}