[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item14. Comparable์„ ๊ตฌํ˜„ํ• ์ง€ ๊ณ ๋ฏผํ•˜๋ผ. (compareTo ๊ธฐ๋ณธ ๊ทœ์•ฝ)

2023. 2. 6. 11:24ใ†JAVA/Effective JAVA

728x90

 

item14. Comparable์„ ๊ตฌํ˜„ํ• ์ง€ ๊ณ ๋ฏผํ•˜๋ผ. 

 

 

compareTo

: compareTo๋Š” Comparable ์ธํ„ฐํŽ˜์ด์Šค์˜ ์œ ์ผํ•œ ๋ฉ”์„œ๋“œ๋กœ Objet.equals(๋‹จ์ˆœ ๋™์น˜์„ฑ)์— ๋”ํ•ด์„œ ์ˆœ์„œ๊นŒ์ง€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Generic์„ ์ง€์›ํ•œ๋‹ค. 

Comparable์„ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ๊ฒƒ์€ ๊ทธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋“ค์—๋Š” ์ž์—ฐ์ ์ธ ์ˆœ์„œ natural order๊ฐ€ ์žˆ์Œ์„ ๋œปํ•œ๋‹ค. 

์•ŒํŒŒ๋ฒณ์ด๋‚˜ ์ˆซ์ž, ์—ฐ๋Œ€์™€ ๊ฐ™์ด ์ˆœ์„œ๊ฐ€ ๋ช…ํ™•ํ•œ ๊ฐ’ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ผ๋ฉด ๋ฐ˜๋“œ์‹œ Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ž. 

 

 

compareTo ์ผ๋ฐ˜ ๊ทœ์•ฝ 

BigDecimal n1 = BigDecimal.valueOf(23134134);
BigDecimal n2 = BigDecimal.valueOf(11231230);
BigDecimal n3 = BigDecimal.valueOf(53534552);
BigDecimal n4 = BigDecimal.valueOf(11231230);

1๏ธโƒฃ Comparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ๋ชจ๋“  x,y์— ๋Œ€ํ•ด sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) ์—ฌ์•ผ ํ•œ๋‹ค. 

-> ๋‘ ๊ฐ์ฒด์˜ ์ฐธ์กฐ์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ” ๋น„๊ตํ•ด๋„ ์˜ˆ์ƒํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์•ผ ํ•œ๋‹ค. 

// p.88 ๋Œ€์นญ์„ฑ
System.out.println("n1.compareTo(n2) = " + n1.compareTo(n2));
System.out.println("n2.compareTo(n1) = " + n2.compareTo(n1));

 

์ฆ‰, ์ฒซ ๋ฒˆ์งธ ๊ฐ์ฒด๊ฐ€ ๋‘ ๋ฒˆ์งธ ๊ฐ์ฒด๋ณด๋‹ค ์ž‘์œผ๋ฉด, ๋‘ ๋ฒˆ์งธ๊ฐ€ ์ฒซ ๋ฒˆ์งธ๋ณด๋‹ค ์ปค์•ผ ํ•œ๋‹ค. 

์ฒซ ๋ฒˆ์งธ๊ฐ€ ๋‘ ๋ฒˆ์งธ์™€ ํฌ๊ธฐ๊ฐ€ ๊ฐ™๋‹ค๋ฉด, ๋‘ ๋ฒˆ์งธ๋Š” ์ฒซ ๋ฒˆ์งธ์™€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. 

์ฒซ ๋ฒˆ์งธ๊ฐ€ ๋‘ ๋ฒˆ์งธ๋ณด๋‹ค ํฌ๋ฉด, ๋‘ ๋ฒˆ์งธ๋Š” ์ฒซ ๋ฒˆ์งธ๋ณด๋‹ค ์ž‘์•„์•ผ ํ•œ๋‹ค. 

 

 

2๏ธโƒฃ Comparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ์ถ”์ด์„ฑ์„ ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค. x.compareTo(y) > 0 && y.compareTo(z) ์ด๋ฉด x.compareTo(z) ์—ฌ์•ผ ํ•œ๋‹ค. 

-> ์ฒซ ๋ฒˆ์งธ๊ฐ€ ๋‘ ๋ฒˆ์งธ๋ณด๋‹ค ํฌ๊ณ  ๋‘ ๋ฒˆ์งธ๊ฐ€ ์„ธ ๋ฒˆ์งธ๋ณด๋‹ค ํฌ๋ฉด, ์ฒซ ๋ฒˆ์งธ๋Š” ์„ธ ๋ฒˆ์งธ๋ณด๋‹ค ์ปค์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. 

// p.89 ์ถ”์ด์„ฑ
System.out.println("n3.compareTo(n1) > 0 = " + (n3.compareTo(n1) > 0));
System.out.println("n1.compareTo(n2) > 0 = " + (n1.compareTo(n2) > 0));
System.out.println("n3.compareTo(n2) > 0 = " + (n3.compareTo(n2) > 0));

 

3๏ธโƒฃ Comparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ๋ชจ๋“  z์— ๋Œ€ํ•ด x.compareTo(y) == ์ด๋ฉด sgn(x.compareTo(z)) == sgn(y.compareTo(z))์ด๋‹ค. 

-> ํฌ๊ธฐ๊ฐ€ ๊ฐ™์€ ๊ฐ์ฒด๋“ค๋ผ๋ฆฌ๋Š” ์–ด๋–ค ๊ฐ์ฒด์™€ ๋น„๊ตํ•˜๋”๋ผ๋„ ํ•ญ์ƒ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. 

// p.89 ์ผ๊ด€์„ฑ
System.out.println("n4.compareTo(n2) = " + n4.compareTo(n2));
System.out.println("n2.compareTo(n1) = " + n2.compareTo(n1));
System.out.println("n4.compareTo(n1) = " + n4.compareTo(n1));

 

4๏ธโƒฃ (x.compareTo(y) == 0) == (x.equals(y)) ์—ฌ์•ผ ํ•œ๋‹ค. (๊ถŒ๊ณ ๊ฐ€ ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ผญ ์ง€ํ‚ค๋Š”๊ฒŒ ์ข‹๋‹ค.)  

Comparable์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ด ๊ถŒ๊ณ ๋ฅผ ์ง€ํ‚ค์ง€ ์•Š๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ๊ทธ ์‚ฌ์‹ค์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค. 

-> compareTo ๋ฉ”์„œ๋“œ๋กœ ์ˆ˜ํ–‰ํ•œ ๋™์น˜์„ฑ ํ…Œ์ŠคํŠธ์˜ ๊ฒฐ๊ณผ๊ฐ€  equals์™€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. 

// p.89 compareTo๊ฐ€ 0์ด๋ผ๋ฉด equals๋Š” true์—ฌ์•ผ ํ•œ๋‹ค. (์•„๋‹ ์ˆ˜๋„ ์žˆ๊ณ ...)
BigDecimal oneZero = new BigDecimal("1.0");
BigDecimal oneZeroZero = new BigDecimal("1.00");
System.out.println("oneZero.compareTo(oneZeroZero) = " + oneZero.compareTo(oneZeroZero)); // Tree, TreeMap
System.out.println("oneZero.equals(oneZeroZero) = " + oneZero.equals(oneZeroZero)); // ์ˆœ์„œ๊ฐ€ ์—†๋Š” ์ปฌ๋ ‰์…˜

-> ์ด ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 

์ด๋ ‡๊ฒŒ equals์™€ compareTo์˜ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

BigDecimal ํด๋ž˜์Šค๋Š” compareTo์™€ equals๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์€ ํด๋ž˜์Šค๋กœ ๋นˆ HashMap ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ ๋‹ค์Œ์— new BigDecimal("1.0"), new Decimal("1.00")์„ ์ฐจ๋ก€๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด ์ด ๋‘ BigDecimal์€ equals ๋ฉ”์„œ๋“œ๋กœ ๋น„๊ตํ•˜๋ฉด ์„œ๋กœ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— HashSet์€ ๋‘๊ฐœ์˜ ์›์†Œ๋ฅผ ๊ฐ€์ง€๋งŒ, 

HashSet ๋Œ€์‹ ์— TreeSet์„ ์‚ฌ์šฉํ•˜๋ฉด ์›์†Œ๋ฅผ ํ•˜๋‚˜๋งŒ ๊ฐ–๊ฒŒ ๋œ๋‹ค. compareTo ๋ฉ”์„œ๋“œ๋กœ ๋น„๊ตํ•˜๋ฉด ๋‘ BigDecimal ์ธ์Šคํ„ด์Šค๊ฐ€ ๋˜‘๊ฐ™๊ธฐ ใ„ธ๋งคใ…œใ„ด์ด๋‹ค. 

/**
 * Compares this {@code BigDecimal} with the specified
 * {@code Object} for equality.  Unlike {@link
 * #compareTo(BigDecimal) compareTo}, this method considers two
 * {@code BigDecimal} objects equal only if they are equal in
 * value and scale (thus 2.0 is not equal to 2.00 when compared by
 * this method).
 *
 * @param  x {@code Object} to which this {@code BigDecimal} is
 *         to be compared.
 * @return {@code true} if and only if the specified {@code Object} is a
 *         {@code BigDecimal} whose value and scale are equal to this
 *         {@code BigDecimal}'s.
 * @see    #compareTo(java.math.BigDecimal)
 * @see    #hashCode
 */
@Override
public boolean equals(Object x) {
    if (!(x instanceof BigDecimal))
        return false;
    BigDecimal xDec = (BigDecimal) x;
    if (x == this)
        return true;
    if (scale != xDec.scale)
        return false;
    long s = this.intCompact;
    long xs = xDec.intCompact;
    if (s != INFLATED) {
        if (xs == INFLATED)
            xs = compactValFor(xDec.intVal);
        return xs == s;
    } else if (xs != INFLATED)
        return xs == compactValFor(this.intVal);

    return this.inflated().equals(xDec.inflated());
}

(thus 2.0 is not equal to 2.00 when compared by this method).

๋ผ๊ณ  ์•Œ๋ ค์ฃผ๊ณ  ์žˆ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90