Item 14. Comparable

Comparable을 κ΅¬ν˜„ν• μ§€ κ³ λ €ν•˜λΌ

compareToλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” Comparable을 κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.(μ•žμ˜ cloneκ³ΌλŠ” λ‹€λ₯΄κ²Œ Objectκ°€ μ•„λ‹Œ Comparable에 μ„ μ–Έλ˜μ–΄ 있음) Comparable을 κ΅¬ν˜„ν•˜λ©΄ μ–΄λ–€ 객체든지 μžμ—°μ μΈ μˆœμ„œλ₯Ό μ •ν•  수 있게 λœλ‹€.(λ°˜λŒ€λ‘œ λ§ν•˜λ©΄, μ •μ˜ν•˜μ§€ μ•Šμ€ 경우 μˆœμ„œλ₯Ό ν•„μš”λ‘œν•˜λŠ” TreeMap, TreeSet λ“±μ—μ„œ μ‚¬μš©ν•  수 μ—†λ‹€.)

compareTo 일반 κ·œμ•½

ν•΄λ‹Ή 객체와 주어진 객체의 μˆœμ„œλ₯Ό λΉ„κ΅ν•˜μ—¬ 주어진 객체보닀 μž‘μœΌλ©΄ 음의 μ •μˆ˜, κ°™μœΌλ©΄ 0, 크면 μ–‘μ˜ μ •μˆ˜λ₯Ό λ°˜ν™˜ν•˜κ³ , 비ꡐ할 수 μ—†λŠ” νƒ€μž… 객체가 주어지면 ClassCastException을 λ˜μ§€λ„λ‘ μ •μ˜ν•œλ‹€. Comparable을 κ΅¬ν˜„ν•œ 클래슀 x, y, z에 λŒ€ν•΄ λ‹€μŒμ˜ κ·œμ•½μ„ 따라야 ν•œλ‹€.

** sgn ν‘œκΈ°: μˆ˜ν•™μ—μ„œ λ§ν•˜λŠ” λΆ€ν˜Έ ν•¨μˆ˜(signum function)λ₯Ό μ˜λ―Έν•˜λ©°, -1, 0, 1 쀑 ν•˜λ‚˜λ₯Ό λ°˜ν™˜ν•˜λ„λ‘ μ •μ˜ν•¨

  • sgn(x.compareTo(y)) == -sgn(y.compareTo(x))

  • x.compareTo(y) > 0 && y.compareTo(z) > 0이면 x.compareTo(z) > 0

  • x.compareTo(y) == 0이면 sgn(x.compareTo(z)) == sgn(y.compareTo(z))

  • (x.compareTo(y) == 0) == (x.equals(y))(ν•„μˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ 일반적으둜 ꢌμž₯)

compareTo κ΅¬ν˜„ 방법

기본적으둜 관계 μ—°μ‚°μž <, >λ₯Ό μ‚¬μš©ν•˜λŠ” λ°©λ²•λ³΄λ‹€λŠ” λ°•μ‹±λœ κΈ°λ³Έ νƒ€μž… 클래슀의 compare 정적 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.(관계 μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λŠ” 방식은 였λ₯˜λ₯Ό λ‚Ό 수 μžˆμ–΄ μΆ”μ²œν•˜μ§€ μ•ŠμŒ) 그리고, 핡심 ν•„λ“œκ°€ μ—¬λŸ¬ 개라면 κ°€μž₯ 핡심적인 ν•„λ“œλΆ€ν„° λΉ„κ΅ν•œ λ’€ μˆœμ„œκ°€ κ²°μ •λ˜λ©΄ μ¦‰μ‹œ λ°˜ν™˜ν•˜μ—¬ λΆˆν•„μš”ν•˜κ²Œ λΉ„κ΅ν•˜λŠ” 일을 μ€„μ΄λŠ” 것이 μ’‹λ‹€.

class PhoneNumber implements Comparable<PhoneNumber> {

    // ...

    @Override
    public int compareTo(PhoneNumber pn) {
        // κ°€μž₯ 핡심적인 ν•„λ“œλΆ€ν„° 비ꡐ
        int result = Short.compare(areaCode, pn.areaCode);
        if (result == 0) { // 같지 μ•ŠμœΌλ©΄ μ‹€ν–‰λ˜μ§€ μ•Šκ³  μ•„λž˜ 라인으둜 λ„˜μ–΄κ°€ λ°”λ‘œ λ°˜ν™˜
            result = Short.compare(prefix, pn.prefix);
            if (result == 0) {
                result = Short.compare(lineNum, pn.lineNum);
            }
        }
        return result;
    }
}

μœ„ λ‚΄μš©μ„ Java 8 μ΄μƒμ—μ„œλŠ” λ©”μ„œλ“œ 연쇄 λ°©μ‹μœΌλ‘œ λΉ„κ΅μžλ₯Ό 생성할 수 μžˆλ‹€.(μ•½κ°„μ˜ μ„±λŠ₯ μ €ν•˜κ°€ μžˆμ„ 수 μžˆμ§€λ§Œ, 가독성이 μ’‹μ•„μ§€λ―€λ‘œ ꢌμž₯)

class PhoneNumber implements Comparable<PhoneNumber> {

    // ...

    private static final Comparator<PhoneNumber> COMPARATOR =
        Comparator.comparingInt((PhoneNumber pn) -> pn.areaCode)
            .thenComparingInt(pn -> pn.prefix)
            .thenComparingInt(pn -> pn.lineNum);
    
    @Override
    public int compareTo(PhoneNumber pn) {
        return COMPARATOR.compare(this, pn);
    }
}

Last updated