๐Ÿ“‚ JAVA/์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”

Comparable์„ ๊ตฌํ˜„ํ• ์ง€ ๊ณ ๋ คํ•˜๋ผ - [3์žฅ. ๋ชจ๋“  ๊ฐ์ฒด์˜ ๊ณตํ†ต ๋ฉ”์„œ๋“œ(์•„์ดํ…œ14)]

Amenable 2023. 4. 11. 23:01

  ์ด๋ฒˆ ๊ธ€์„ ํ†ตํ•ด Comparable์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ์ข‹์„์ง€ ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค. ์šฐ์„ ์€ 'compareTo ๊ทœ์•ฝ'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ณ  'compareTo๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค. (๋งŒ์•ฝ Comparable์— ๋Œ€ํ•œ ๊ธฐ๋ณธ์ง€์‹์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ด์ „ ๊ธ€์„ ์ฐธ๊ณ ํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.)

  ๋“ค์–ด๊ฐ€๊ธฐ์— ์•ž์„œ Comparable ์ธํ„ฐํŽ˜์ด์Šค์˜ ์œ ์ผ๋ฌด์ดํ•œ ๋ฉ”์„œ๋“œ์ธ compareTo์˜ ํŠน์ง•์— ๋Œ€ํ•ด์„œ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž. ์ด๋Š” ์•„๋ž˜์˜ 2๊ฐ€์ง€๋งŒ ๋นผ๋ฉด Object.equals์™€ ๊ฐ™๋‹ค.

  1. ๋‹จ์ˆœ ๋™์น˜์„ฑ ๋น„๊ต์— ๋”ํ•ด์„œ ์ˆœ์„œ๊นŒ์ง€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. Generic์„ ์ง€์›ํ•œ๋‹ค.

 

1. compareTo ๊ทœ์•ฝ ๐Ÿช”

  sgn(ํ‘œํ˜„์‹) ํ‘œ๊ธฐ๋Š” ์ˆ˜ํ•™์—์„œ ๋งํ•˜๋Š” ๋ถ€ํ˜ธ ํ•จ์ˆ˜๋ฅผ ๋œปํ•˜๋ฉฐ, ํ‘œํ˜„์‹์˜ ๊ฐ’์ด ์Œ์ˆ˜, 0, ์–‘์ˆ˜ ์ผ ๋•Œ -1, 0, 1์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ •์˜ํ–ˆ๋‹ค.

  1. ๋ฐ˜์‚ฌ์„ฑ
    x.compareTo(y) == 0 ์ด๋ฉด sgn(x.compareTo(z)) == sgn(y.compareTo(z))
  2. ๋Œ€์นญ์„ฑ
    sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
  3. ์ถ”์ด์„ฑ
    (x.compareTo(y) > 0 && y.compareTo(z) > 0)์ด๋ฉด x.compareTo(z) > 0์ด๋‹ค.
  4. equals๋Š” ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ผญ ์ง€ํ‚ค๋Š” ๊ฒŒ ์ข‹๋‹ค.
    (x.compareTo(y) == 0) == (x.equals(y))
    Comparable์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ด ๊ถŒ๊ณ ๋ฅผ ์ง€ํ‚ค์ง€ ์•Š๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ๊ทธ ์‚ฌ์‹ค์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.

  compareTo์™€ equals๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š๋Š” ์˜ˆ์‹œ๋กœ๋Š” BigDecimal ํด๋ž˜์Šค๊ฐ€ ์žˆ๋‹ค.

public static void main(String[] args) {
    BigDecimal oneZero = new BigDecimal("1.0");
    BigDecimal oneZeroZero = new BigDecimal("1.00");
    System.out.println(oneZero.compareTo(oneZeroZero)); // 0 
    System.out.println(oneZero.equals(oneZeroZero)); // false
}

 

2. ์ •์  compare ๋ฉ”์„œ๋“œ ๐Ÿ’ก

  compareTo๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฐฉ์‹์€ '์ •์  compare ๋ฉ”์„œ๋“œ'๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

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;
}

์ฐธ๊ณ ํ•  ์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž… ํด๋ž˜์Šค๋“ค์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ์ •์  ๋ฉ”์„œ๋“œ์ธ compare๋ฅผ ์ด์šฉํ•ด์„œ ๋น„๊ตํ•˜๋ฉด ๋œ๋‹ค.
  • compareTo ๋ฉ”์„œ๋“œ์—์„œ ๊ด€๊ณ„ ์—ฐ์‚ฌ์ž์ธ '<'์™€ '>'๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ „ ๋ฐฉ์‹์€ ๊ฑฐ์ถ”์žฅ์Šค๋Ÿฝ๊ณ  ์˜ค๋ฅ˜๋ฅผ ์œ ๋ฐœํ•˜๋‹ˆ, ์ด์ œ๋Š” ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ํด๋ž˜์Šค์— ํ•ต์‹ฌ ํ•„๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ํ•ต์‹ฌ์ ์ธ ํ•„๋“œ๋ถ€ํ„ฐ ๋น„๊ตํ•ด ๋‚˜๊ฐ€๋ฉด ๋œ๋‹ค.

  ๊ธฐ์กด ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๊ณ  ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ compareTo ๊ทœ์•ฝ์„ ์ง€ํ‚ฌ ์ˆ˜ ์—†๋‹ค. (ํ•˜์œ„ํƒ€์ž…์—์„œ ๋‹ค์‹œ Comparable์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†๋‹ค.)

  ์ด๋Ÿฐ ๊ฒฝ์šฐ Composition์„ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค. (equals ๊ทœ์•ฝ์„ ์ง€ํ‚ค๋ฉด์„œ ํ™œ์šฉํ•  ๋•Œ ์ƒ์†์ด ์•„๋‹Œ Composition์„ ๊ถŒ๊ณ ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋งฅ๋ฝ์ด๋‹ค.)

public class Point implements Comparable<Point> {
	
	final int x, y;

	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	@Override
	public int compareTo(Point point) {
		int result = Integer.compare(this.x, point.x);
		if(result == 0) {
			result = Integer.compare(this.y, point.y);
		}
		return result;
	}
}

----------

public class NamedPoint implements Comparable<NamedPoint> {

	private final Point point;
	private final String name;
	
	public NamedPoint(Point point, String name) {
		this.point = point;
		this.name = name;
	}
	
	// ๋‚ด๋ถ€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” '๋ทฐ'๋ฉ”์„œ๋“œ
	public Point getPoint() {
		return this.point;
	}

	@Override
	public int compareTo(NamedPoint namedPoint) {
		int result = this.point.compareTo(namedPoint.point);
		if(result == 0) {
			result = this.name.compareTo(namedPoint.name);
		}
		return result;
	}
}

 

3. ๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ ๐Ÿ”ฆ

  compareTo๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๋ฒˆ์งธ ๋ฐฉ์‹์€ '๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ'๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ž๋ฐ” 8๋ถ€ํ„ฐ๋Š” 'ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค, ๋žŒ๋‹ค, ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค'์™€ 'Comparator๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ์™€ static ๋ฉ”์„œ๋“œ'๋ฅผ ์‚ฌ์šฉํ•ด์„œ Comparator๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

  Comparator๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค

  1. Comparator์˜ static ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ Comparator ์ธ์Šคํ„ด์Šค ๋งŒ๋“ค๊ธฐ
  2. default ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ด์–ด๋‚˜๊ฐ€๊ธฐ (์ฒด์ด๋‹)
    ์ด๋•Œ, static ๋ฉ”์„œ๋“œ์™€ default ๋ฉ”์„œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹ ๋˜๋Š” ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
// ๋žŒ๋‹ค ํ‘œํ˜„์‹ ํ™œ์šฉ
private static final Comparator<PhoneNumber> COMPARATOR = 
    comparingInt((PhoneNumber pn) -> pn.areaCode)
        .thenComparingInt(pn -> pn.prefix)
        .thenComparingInt(pn -> pn.lineNum);

public int comareTo(PhoneNumber pn) {
    return COMPARATOR.compare(this, pn);
}
// ๋ฉ”์„œ๋“œ ๋ ˆํผ๋Ÿฐ์Šค ํ™œ์šฉ
private static final Comparator<PhoneNumber> COMPARATOR = 
    comparingInt((PhoneNumber pn) -> pn.areaCode)
        .thenComparingInt(PhoneNumber::getPrefix)
        .thenComparingInt(PhoneNumber::getLineNum);

public int comareTo(PhoneNumber pn) {
    return COMPARATOR.compare(this, pn);
}

  Comparator์—๋Š” ์ˆ˜๋งŽ์€ ๋ณด์กฐ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ์ฒด ์ฐธ์กฐ์šฉ ๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๋„ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.

 

4. ์ •๋ฆฌ ๐Ÿฎ

  • ์ˆœ์„œ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๊ฐ’ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ๊ผญ Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ, ๊ทธ ์ธ์Šคํ„ด์Šค๋“ค์„ ์‰ฝ๊ฒŒ ์ •๋ ฌํ•˜๊ณ , ๊ฒ€์ƒ‰ํ•˜๊ณ , ๋น„๊ต ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์ปฌ๋ ‰์…˜๊ณผ ์–ด์šฐ๋Ÿฌ์ง€๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
  • compareTo ๋ฉ”์„œ๋“œ์—์„œ ํ•„๋“œ์˜ ๊ฐ’์„ ๋น„๊ตํ•  ๋•Œ '<'์™€ '>' ์—ฐ์‚ฐ์ž๋Š” ์“ฐ์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค.
  • ๊ทธ ๋Œ€์‹  ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž… ํด๋ž˜์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” '์ •์  compare ๋ฉ”์„œ๋“œ'๋‚˜ Comparator ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ œ๊ณตํ•˜๋Š” '๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ'๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

ํ•ด๋‹น ๊ธ€์€ ๋ฐฑ๊ธฐ์„  ๋‹˜์˜ '์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” ์™„๋ฒฝ ๊ณต๋žต'์„ ์ˆ˜๊ฐ•ํ•˜๊ณ  ์ž‘์„ฑํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.