Java Comparable vs Compartor ์‚ฌ์šฉ๋ฐฉ๋ฒ•

์ž๋ฐ” Comparable๊ณผ Comparator์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.

์ผ๋ฐ˜์ ์ธ ์ •๋ ฌ

์ผ๋ฐ˜์ ์ธ primitive ํƒ€์ž… ์ •๋ ฌ์€ java์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

public static void main(final String[] args) {
    final int[] intArray = {1, 5, 3, 7, 8, 3};
    Arrays.sort(intArray);
    System.out.println(Arrays.toString(intArray));

    final List<String> list = Arrays.asList("a", "c", "d", "e", "b", "f");
    Collections.sort(list);
    System.out.println(list);
}

๊ฒฐ๊ณผ

[1, 3, 3, 5, 7, 8]
[a, b, c, d, e, f]

Arrays.sort(), Collections.sort()์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์ด ์–ด๋–ป๊ฒŒ ๋˜์–ด ์žˆ๋Š”์ง€๋Š” ์ถ”๊ฐ€๋กœ ํ•™์Šต

๊ฐ์ฒด ์ •๋ ฌ?

์ด๋ฒˆ์—๋Š” ๊ฐ์ฒด๋ฅผ ์ •๋ ฌํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ? ๊ทธ๋ƒฅ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๊ธฐ์ค€์ด ๋˜๋Š” ๊ฐ’์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ํŒ๋‹จํ•  ์ˆ˜ ์—†๊ฒ ๊ตฌ๋‚˜ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ๊ฐ„๋‹จํ•œ Userํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

public class User{

    private final int id;
    private final String name;
    private final int age;

    public User(final int id, final String name, final int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // getter ์ƒ๋žต

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3๋ช…์˜ ์œ ์ €๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐฐ์—ด sort๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด cannot be cast to Comparable class cast ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

public static void main(final String[] args) {
    final User andrew = new User(1, "andrew", 32);
    final User berry = new User(2, "berry", 26);
    final User robert = new User(3, "robert", 28);
    final User[] users = {andrew, berry, robert};

    Arrays.sort(users);

    System.out.println(Arrays.toString(users));
}
Exception in thread "main" java.lang.ClassCastException: com.example.demo.comparator.User cannot be cast to java.lang.Comparable
	at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.util.Arrays.sort(Arrays.java:1246)
	at com.example.demo.comparator.ComparableTest.main(ComparableTest.java:27)

๋ฐฉ๋ฒ•1 - Comparable ๊ตฌํ˜„

๋‹ค์‹œ Userํด๋ž˜์Šค๋กœ ๋Œ์•„๊ฐ€์„œ, Comparable์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

public class User implements Comparable {

    private final int id;
    private final String name;
    private final int age;

    // ์ƒ๋žต

    @Override
    public int compareTo(Object o) {
        if (o instanceof User) {
            User user = (User) o;
            return this.age - user.age;
        }
        return 0;
    }

ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด, ๋ฐ˜๋“œ์‹œ compareTo๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์œผ๋กœ ๊ตฌํ˜„ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๋ฉ”์„œ๋“œ ์•ˆ์˜ ๋‚ด์šฉ์€ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์–ด๋–ค ํ•„๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ์„ ํ•  ๊ฒƒ์ธ์ง€ ๊ตฌํ˜„ํ•œ๋‹ค. ๋‚˜์ด์ˆœ์œผ๋กœ ์ •๋ ฌ ํ•˜๋„๋ก ์ž‘์„ฑํ–ˆ๋‹ค. ๋‹ค์‹œ ๋ฉ”์ธ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

[User{id=2, name='berry', age=26}, User{id=3, name='robert', age=28}, User{id=1, name='andrew', age=32}]

age์ˆœ์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ์ด ๋˜์—ˆ๋‹ค. ํ•˜์ง€๋งŒ, Comparable์˜ ๋‹จ์ ์€ ํด๋ž˜์Šค๋‹น ํ•˜๋‚˜์˜ compareTo ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ • ์ •๋ ฌ ๊ธฐ์ค€๋งŒ์„ ์ถฉ์กฑ์‹œํ‚จ๋‹ค. ๋‹ค์ด๋‚˜๋ฏนํ•˜๊ฒŒ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋น„๊ต์ž๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ฃผ์ž…ํ•  ์ˆ˜ ๋Š” ์—†์„๊นŒ?

๋ฐฉ๋ฒ•2 - Comparator ๊ตฌํ˜„

Comparator๋Š” Functional Interface๋กœ ํ•˜๋‚˜์˜ ์ถ”์ƒ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ต๋ช… ํ•จ์ˆ˜ ์ด๊ธฐ๋„ ํ•˜๋‹ค. ๊ฒฐ๊ตญ ๋žŒ๋‹ค์‹์œผ๋กœ ํ‘œํ˜„์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ •๋ ฌ์„ ํ• ๋•Œ, 2๋ฒˆ์งธ ์ธ์ž๋กœ ํ•ด๋‹น Comparator๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด์˜ Comparable ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„ ๋ถ€๋ฅผ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์–‘ํ•œ Comparaotr๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์ž.

public class User {

    private final int id;
    private final String name;
    private final int age;

    public User(final int id, final String name, final int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // ์ƒ๋žต

    public static Comparator<User> nameComparator = (o1, o2) -> o1.name.compareTo(o2.name);

    public static Comparator<User> ageComparator = (o1, o2) -> o1.age - o2.age;

Userํด๋ž˜์Šค์— nameComparator, ageComparator๋ฅผ ๊ฐ๊ฐ ๋งŒ๋“ค๊ณ , ๋žŒ๋‹ค์‹์„ ํ†ตํ•ด์„œ ์ž‘์„ฑํ–ˆ๋‹ค. ์‹ค์ œ ์‚ฌ์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด 2๋ฒˆ์งธ ์ธ์ž๋กœ ์›ํ•˜๋Š” Comparator๋ฅผ ๋„˜๊ธด๋‹ค.

public static void main(final String[] args) {
        final User andrew = new User(1, "andrew", 32);
        final User berry = new User(2, "berry", 26);
        final User robert = new User(3, "robert", 28);

        final User[] users = {andrew, berry, robert};
        // ๋‚˜์ด์ˆœ์œผ๋กœ ์ •๋ ฌ
        Arrays.sort(users,  User.ageComparator);
        System.out.println(Arrays.toString(users));

        final List<User> userList = Arrays.asList(andrew, berry, robert);
        // ์ด๋ฆ„์ˆœ์œผ๋กœ ์ •๋ ฌ
        Collections.sort(userList, User.nameComparator);
        System.out.println(userList);
    }
}
[User{id=2, name='berry', age=26}, User{id=3, name='robert', age=28}, User{id=1, name='andrew', age=32}]
[User{id=1, name='andrew', age=32}, User{id=2, name='berry', age=26}, User{id=3, name='robert', age=28}]

๋‚˜์ด์ˆœ์œผ๋กœ, ์ด๋ฆ„์ˆœ์œผ๋กœ ์ •๋ ฌ๋จ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋” ์ƒ๊ฐํ•ด ๋ณผ ๊ฒƒ

์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” Comparator๋ฅผ ์ €๋ ‡๊ฒŒ ํด๋ž˜์Šค์•ˆ์— ๋„ฃ๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ณ , ์‚ฌ์‹ค ์‚ฌ์šฉํ•˜๋Š” ์ชฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋„˜๊ฒจ์ค„ ์ˆ˜ ๋„ ์žˆ๋‹ค.

Arrays.sort(users,  (o1, o2) -> o1.age - o2.age);

ํ•˜์ง€๋งŒ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์ž. ๋‚˜์ด์ˆœ์ด ์•„๋‹ˆ๋ผ, ์–ด๋–ค ํŠน์ •ํ•œ ์กฐ๊ฑด์œผ๋กœ ์ƒˆ๋กญ๊ฒŒ ์ •๋ ฌ ํ•œ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ ๊ธฐ์กด์˜ ageCompartor๋กœ ๊ตฌํ˜„ํ–ˆ๋”๋ผ๋ฉด ์ด๋ฆ„๊ณผ ๋‚ด๋ถ€ ๊ตฌํ˜„๋งŒ ๋ฐ”๊พธ๋ฉด ์‚ฌ์šฉํ•˜๋Š” ์ชฝ ์ฝ”๋“œ๋ฅผ ์ „ํ˜€ ์†๋Œ€์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์ผ์ผ์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ๋„˜๊ธฐ๋Š” ํ˜•ํƒœ์˜€๋‹ค๋ฉด?? ๋ชจ๋“  ๊ด€๋ จ๋œ ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ์ฐพ์•„์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒซ๋ฒˆ์งธ ํŠน์ • ํด๋ž˜์Šค๋‚ด์— ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” Compartor๋ฅผ ๊ตฌํ˜„ํ•ด ๋†“๋Š” ๊ฒŒ ํ›จ์”ฌ ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

์—ฐ๊ด€ ํฌ์ŠคํŠธ