[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (equals ๊ตฌํ˜„ ๋ฐฉ๋ฒ•๊ณผ ์ฃผ์˜์‚ฌํ•ญ)

2023. 1. 26. 16:54ใ†JAVA/Effective JAVA

728x90
item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. 

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (๋Œ€์นญ์„ฑ, ๋ฐ˜์‚ฌ์„ฑ, ์ถ”์ด์„ฑ) (tistory.com)

 

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (๋Œ€์นญ์„ฑ, ๋ฐ˜์‚ฌ์„ฑ, ์ถ”์ด์„ฑ)

item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. equals ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค. equals ๊ทœ์•ฝ 1๏ธโƒฃ ๋ฐ˜์‚ฌ์„ฑ reflexivity : null ์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x์— ๋Œ€ํ•ด x.equals(x) == true

hyejin.tistory.com

 

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (์ถ”์ด์„ฑ, ์ผ๊ด€์„ฑ, null-์•„๋‹˜) (tistory.com)

 

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (์ถ”์ด์„ฑ, ์ผ๊ด€์„ฑ, null-์•„๋‹˜)

item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. equals ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ๋”ฐ๋ผ์•ผ ํ•œ๋‹ค. [์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item10. equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ. (๋Œ€์นญ์„ฑ, ๋ฐ˜์‚ฌ์„ฑ, ์ถ”์ด

hyejin.tistory.com

 

์•ž์—์„œ equals ์ผ๋ฐ˜ ๊ทœ์•ฝ์— ๋Œ€ํ•ด์„œ ํ•™์Šตํ–ˆ๊ณ , equals ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์ •๋ฆฌํ•œ๋‹ค. 

 

 

equals ๊ตฌํ˜„๋ฐฉ๋ฒ•

 

1๏ธโƒฃ == ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์ž…๋ ฅ์ด ์ž๊ธฐ ์ž์‹ ์˜ ์ฐธ์กฐ์ธ์ง€ ํ™•์ธํ•œ๋‹ค. 

if (this == obj) {
   return true;
}

์ž๊ธฐ ์ž์‹ ์ด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

-> ์ด๋Š” ๋‹จ์ˆœํ•œ ์„ฑ๋Šฅ ์ตœ์ ํ™”์šฉ์œผ๋กœ, ๋น„๊ต ์ž‘์—…์ด ๋ณต์žกํ•œ ์ƒํ™ฉ์ผ ๋•Œ ๊ฐ’์–ด์น˜๋ฅผ ํ•  ๊ฒƒ์ด๋‹ค. 

 

2๏ธโƒฃ instanceof ์—ฐ์‚ฐ์ž๋กœ ์ž…๋ ฅ์ด ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์ธ์ง€ ํ™•์ธํ•œ๋‹ค. 

if (!(obj instanceof Point)) {
   return false;
}

-> ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

3๏ธโƒฃ ์ž…๋ ฅ์„ ์˜ฌ๋ฐ”๋ฅธ ํƒ€์ž…์œผ๋กœ ํ˜•๋ณ€ํ™˜ํ•œ๋‹ค. 

Point p = (Point) obj;

-> 2๋‹จ๊ณ„์—์„œ instanceof ๊ฒ€์‚ฌ๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๊ณตํ•œ๋‹ค. 

 

4๏ธโƒฃ ์ž…๋ ฅ ๊ฐ์ฒด์™€ ์ž๊ธฐ ์ž์‹ ์˜ ๋Œ€์‘๋˜๋Š” 'ํ•ต์‹ฌ' ํ•„๋“œ๋“ค์ด ๋ชจ๋‘ ์ผ์น˜ํ•˜๋Š”์ง€ ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌํ•œ๋‹ค. 

return p.x == x && p.y == y;

๋ชจ๋“  ํ•„๋“œ๋“ค์ด ์ผ์น˜ํ•˜๋ฉด true๋ฅผ, ํ•˜๋‚˜๋ผ๋„ ๋‹ค๋ฅด๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

์ด๋•Œ float์™€ double์„ ์ œ์™ธํ•œ ๊ธฐ๋ณธ ํƒ€์ž… ํ•„๋“œ๋Š” ==์—ฐ์‚ฐ์ž๋กœ ๋น„๊ตํ•˜๊ณ , ์ฐธ์กฐ ํƒ€์ž… ํ•„๋“œ๋Š” ๊ฐ๊ฐ equals ๋ฉ”์„œ๋“œ๋กœ, float์™€ double ํ•„๋“œ๋Š” ๊ฐ๊ฐ ์ •์  ๋ฉ”์„œ๋“œ์ธ Float.compare(float, float)์™€ Double.compare(double, double) ๋กœ ๋น„๊ตํ•œ๋‹ค. float์™€ double์€ ๋ถ€๋™ ์†Œ์ˆ˜๊ฐ’์„ ๋‹ค๋ค„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ๋•Œ๋ก  null ๋„ ์ •์ƒ ๊ฐ’์œผ๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ์ฐธ์กฐ  ํƒ€์ž… ํ•„๋“œ๋„ ์žˆ๋Š”๋ฐ ์ด๋Ÿฐ ํ•„๋“œ๋Š” ์ •์  ๋ฉ”์„œ๋“œ์ธ Objects.equals(Object, Object)๋กœ ๋น„๊ตํ•ด์„œ NPE๋ฅผ ์˜ˆ๋ฐฉํ•˜๋ฉด ๋œ๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ํ•„๋“œ๋ฅผ ๋จผ์ € ๋น„๊ตํ•˜๋А๋ƒ๊ฐ€ equals์˜ ์„ฑ๋Šฅ์„ ์ขŒ์šฐํ•˜๊ธฐ๋„ ํ•œ๋‹ค. 

์ตœ์ƒ์˜ ์„ฑ๋Šฅ์„ ๋ฐ”๋ž€๋‹ค๋ฉด ๋‹ค๋ฅผ ๊ฐ€๋Šฅ์„ฑ์ด ๋” ํฌ๊ฑฐ๋‚˜ ๋น„๊ตํ•˜๋Š” ๋น„์šฉ์ด ์‹ผ ํ•„๋“œ๋ฅผ ๋จผ์ € ๋น„๊ตํ•˜๋ฉด ์ข‹๋‹ค. 

 

 

๐Ÿค— equals ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• ์ •๋ฆฌ 

equals๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ equals ์ž‘์„ฑ์„ ๋„์™€์ฃผ๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ๋‹ค. 

 

- ๊ตฌ๊ธ€์˜ AutoValue 

์šฐ์„  build.gradle์— 

compileOnly             "com.google.auto.value:auto-value-annotations:1.6"
annotationProcessor "com.google.auto.value:auto-value:1.6"

๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  gradle ํ•œ๋ฒˆ refresh ํ•ด์ค€๋‹ค. 

 

@AutoValue
abstract class Point
{
   static Point create(int x, int y)
   {
      return new AutoValue_Point(x, y); //  IDE์—์„œ๋Š” ์—†๋‹ค๊ณ  ํ•˜์ง€๋งŒ ์ปดํŒŒ์ผ ํ•  ๋•Œ ๋งŒ๋“ค์–ด์ค€๋‹ค.
   }
   
   abstract int x();
   
   abstract int y();

}

๊ทธ๋ฆฌ๊ณ  AutoValue_Point๊ฐ€ IDE์—์„œ๋Š” ์—†๋‹ค๊ณ  ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋œฐ ๊ฒƒ์ด์ง€๋งŒ ์ปดํŒŒ์ผ ์‹œ์ ์— AutoValue_Point๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค!! (์ฆ‰, ์—๋Ÿฌ ์•„๋‹ˆ๋ž€ ์†Œ๋ฆฌ) 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package chapter01.item10.autovalue;

final class AutoValue_Point extends Point {
    private final int x;
    private final int y;

    AutoValue_Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    int x() {
        return this.x;
    }

    int y() {
        return this.y;
    }

    public String toString() {
        return "Point{x=" + this.x + ", y=" + this.y + "}";
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Point)) {
            return false;
        } else {
            Point that = (Point)o;
            return this.x == that.x() && this.y == that.y();
        }
    }

    public int hashCode() {
        int h$ = 1;
        h$ *= 1000003;
        h$ ^= this.x;
        h$ *= 1000003;
        h$ ^= this.y;
        return h$;
    }
}

-> build -> classes ๋กœ ๊ฐ€๋ณด๋ฉด AutoValue_Point๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

๊ทผ๋ฐ ์ด ๊ตฌ๊ธ€์˜ AutoValue๋Š” ์นจํˆฌ์ ์ด๊ธฐ๋„ ํ•ด์„œ ์ด ๊ฐ•์˜์˜ ๊ฐ•์‚ฌ๋‹˜์€ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ–ˆ๋‹ค. 

 

 

- Lombok

๋Œ€๋ถ€๋ถ„ ์ด Lombok์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค. 

@EqualsAndHashCode
@ToString
public class Point
{
   private final int x;
   
   private final int y;
   
   public Point(int x, int y)
   {
      this.x = x;
      this.y = y;
   }
}

๋กฌ๋ณต์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋„ ์ค„๊ณ  ์ข‹๋‹ค. (์•ฝ๊ฐ„์˜ ๋…ผ๋ž€? ์ด ์žˆ๊ธฐ๋Š” ํ•˜์ง€๋งŒ.. ์‚ฌ์šฉ์— ๋ฌด๋ฆฌ๋Š” ์—†๋‹ค๊ณ  ํ•œ๋‹ค.) 

 

 

- IDE ์˜ ์ฝ”๋“œ ์ƒ์„ฑ ๊ธฐ๋Šฅ ์‚ฌ์šฉ 

์ด๋Ÿฐ์‹์œผ๋กœ ์ธํ…”๋ฆฌ์ œ์ด์—์„œ๋Š” equals์™€ hascode ์ƒ์„ฑ์„ ๋„์™€์ค€๋‹ค. 

public class Point
{
   private final int x;
   
   private final int y;
   
   public Point(int x, int y)
   {
      this.x = x;
      this.y = y;
   }
   
   // IDE ์‚ฌ์šฉ -> ๋‹จ์ : ์ฝ”๋“œ๊ฐ€ ์ง€์ €๋ถ„ํ•ด์ง„๋‹ค, ํ•„๋“œ๊ฐ€ ๋Š˜์–ด๋‚˜๋ฉด ๋‹ค์‹œ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
   @Override
   public boolean equals(Object o)
   {
      if (this == o)
         return true;
      if (o == null || getClass() != o.getClass())
         return false;
      Point point = (Point) o;
      return x == point.x && y == point.y;
   }
   
   @Override
   public int hashCode()
   {
      return Objects.hash(x, y);
   }
}

-> ์—ฌ๊ธฐ์„œ ๋‹จ์ ์€ ์ฝ”๋“œ๊ฐ€ ์ง€์ €๋ถ„ํ•ด์ง„๋‹ค๋Š” ์ ๊ณผ  ํ•„๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค๋Š” ์ ์ด ์žˆ๋‹ค!! (ํ•„๋“œ๋Š” ์ถ”๊ฐ€ํ•˜๊ณ  equals ์™€ hascode๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ํฐ์ผ๋‚œ๋‹ค ใ…Žใ…Ž )

 

 

equals ์ฃผ์˜์‚ฌํ•ญ 

 

1๏ธโƒฃ equals๋ฅผ ์žฌ์ •์˜ํ•  ๋• hashcode๋„ ๋ฐ˜๋“œ์‹œ ์žฌ์ •์˜ํ•ด์•ผํ•œ๋‹ค. 

 

2๏ธโƒฃ ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜๋ ค ๋“ค์ง€ ๋ง์ž!

ํ•„๋“œ๋“ค์˜ ๋™์น˜์„ฑ๋งŒ ๊ฒ€์‚ฌํ•ด๋„ equals ๊ทœ์•ฝ์„ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ์˜คํžˆ๋ ค ๋„ˆ๋ฌด ๊ณต๊ฒฉ์ ์œผ๋กœ ํŒŒ๊ณ ๋“ค๋‹ค๊ฐ€ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 

 

3๏ธโƒฃ Object ์™ธ์˜ ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” equals ๋ฉ”์„œ๋“œ๋Š” ์„ ์–ธํ•˜์ง€ ๋ง์ž. 

 

public boolean equals(Point obj)
{
	...
}

์ด๋Ÿฐ์‹์œผ๋กœ ์ž…๋ ฅํƒ€์ž…์„ Object๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์œผ๋ฉด ์•ˆ๋œ๋‹ค..!! 

์ด๊ฑด ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ์•„๋‹ˆ๋ผ ์˜ค๋ฒ„๋กœ๋”ฉ์ด ๋œ๋‹ค... 

 

 

 

 

 

 

 

 

 

 

728x90