[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item11. equals๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๊ฑฐ๋“  hashcode๋„ ์žฌ์ •์˜ํ•˜๋ผ. (hashCode ๊ทœ์•ฝ)

2023. 1. 30. 11:08ใ†JAVA/Effective JAVA

728x90

 

item11. equals๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๊ฑฐ๋“  hashcode๋„ ์žฌ์ •์˜ํ•˜๋ผ. 

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

 

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

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

hyejin.tistory.com

equals๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ hashcode๋„ ๋ฐ˜๋“œ์‹œ ์žฌ์ •์˜ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ฃผ์˜์‚ฌํ•ญ์œผ๋กœ ์ž‘์„ฑํ•ด๋’€๋‹ค. 

 

equals๋ฅผ ์žฌ์ •์˜ํ•œ ํด๋ž˜์Šค ๋ชจ๋‘์—์„œ hashcode๋„ ์žฌ์ •์˜ํ•ด์•ผํ•˜๋Š”๋ฐ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด hashcode ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์–ด๊ธฐ๊ฒŒ ๋˜์–ด์„œ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ HashMap์ด๋‚˜ HashSet ๊ฐ™์€ ์ปฌ๋ ‰์…˜์˜ ์›์†Œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. 

 

 

hashCode ๊ทœ์•ฝ

 

1๏ธโƒฃ equals ๋น„๊ต์— ์‚ฌ์šฉํ•˜๋Š” ์ •๋ณด๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด hashCode๋Š” ๋งค๋ฒˆ ๊ฐ™์€ ๊ฐ’์„ ๋ฆฌํ„ดํ•ด์•ผ ํ•œ๋‹ค. 

(๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ์‹คํ–‰ํ–ˆ๋‹ค๋ฉด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.) 

 

 

2๏ธโƒฃ ๋‘ ๊ฐ์ฒด์— ๋Œ€ํ•œ equals๊ฐ€ ๊ฐ™๋‹ค๋ฉด, hashCode์˜ ๊ฐ’๋„ ๊ฐ™์•„์•ผ ํ•œ๋‹ค. 

 

 

3๏ธโƒฃ ๋‘ ๊ฐ์ฒด์— ๋Œ€ํ•œ equals๊ฐ€ ๋‹ค๋ฅด๋”๋ผ๋„, hashCode์˜ ๊ฐ’์€ ๊ฐ™์„ ์ˆ˜ ์žˆ์ง€๋งŒ ํ•ด์‹œ ํ…Œ์ด๋ธ” ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ•ด ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. 

 

 

-> ์—ฌ๊ธฐ์„œ hashcode ์žฌ์ •์˜๋ฅผ ์ž˜๋ชปํ–ˆ์„ ๋•Œ ํฌ๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๊ณณ์€ 2๋ฒˆ์งธ๋กœ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐ™์€ ๊ฐ์ฒด๋Š” ๊ฐ™์€ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. 

 

public class PhoneNumber
{
   private final short areaCode, prefix, lineNum;
   
   public PhoneNumber(int areaCode, int prefix, int lineNum)
   {
      this.areaCode = rangeCheck(areaCode, 999, "area code");
      this.prefix = rangeCheck(prefix, 999, "prefix");
      this.lineNum = rangeCheck(lineNum, 9999, "line num");
   }
   
   private static short rangeCheck(int val, int max, String arg)
   {
      if (val < 0 || val > max) {
         throw new IllegalArgumentException(arg + ": " + val);
      }
         return (short) val;
   }
   
   @Override
   public boolean equals(Object o)
   {
      if (this == o)
         return true;
      if (!(o instanceof PhoneNumber)) {
         return false;
      }
      PhoneNumber that = (PhoneNumber) o;
      return areaCode == that.areaCode && prefix == that.prefix && lineNum == that.lineNum;
   }
 }

์ด๋ ‡๊ฒŒ ๋งŒ์•ฝ equals๋Š” ์žฌ์ •์˜ ํ–ˆ๋Š”๋ฐ hashcode๋Š” ์žฌ์ •์˜ํ•˜์ง€ ์•Š์•˜๋”๋ผ๋ฉด 

 

    public static void main(String[] args)
   {
      Map<PhoneNumber, String> map = new WeakHashMap<>();
      PhoneNumber number1 = new PhoneNumber(123, 456, 7890);
      PhoneNumber number2 = new PhoneNumber(123, 456, 7890);
      
      // ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์ธ๋ฐ ๋‹ค๋ฅธ hashcode
      System.out.println("number1.equals(number2) = " + number1.equals(number2));
      System.out.println("number1.hashCode() = " + number1.hashCode());
      System.out.println("number2.hashCode() = " + number2.hashCode());
      
      map.put(number1, "hyejin");
      map.put(number2, "user");
      
      String s = map.get(number2);
      System.out.println("s = " + s);
      
      String s1 = map.get(new PhoneNumber(123, 456, 7890));
	  System.out.println("s1 = " + s1); // ์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋‚˜์˜ด
      
   }

number1๊ณผ number2 ๋ฅผ map์— ๋„ฃ๊ณ  map.get(number2)๋ฅผ ํ•  ๋•Œ๋Š” user์„ ์ž˜ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ 

๋ฐ‘์— new PhoneNumber(123, 456, 7890)์„ getํ•˜๋ฉด null์ด ๋ฐ˜ํ™˜๋œ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

์™œ๋ƒํ•˜๋ฉด hashcode๋ฅผ ๊ฐ™์ด ์žฌ์ •์˜ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋…ผ๋ฆฌ์  ๋™์น˜์ธ ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

๋”ฐ๋ผ์„œ get ๋ฉ”์„œ๋“œ๊ฐ€ ํ•ด์‹œ ์ฝ”๋“œ๊ฐ’์ด ๋‹ฌ๋ผ์„œ ๋‹ค๋ฅธ ๊ณณ์„ ์ฐพ์•„ ํ—ค๋งค๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— null์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

 

๐Ÿ“š HashMap์€ ํ•ด์‹œ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฅธ ์—”ํŠธ๋ฆฌ๋ผ๋ฆฌ๋Š” ๋™์น˜์„ฑ ๋น„๊ต ์‹œ๋„์กฐ์ฐจ ํ•˜์ง€ ์•Š๋„๋ก ์ตœ์ ํ™” ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

 

๊ทธ๋ž˜์„œ hashcode๋ฅผ ์žฌ์ •์˜ํ•ด์•ผํ•˜๋Š”๋ฐ ๋งŒ์•ฝ hashcode ๊ฐ’์„ ๋ชจ๋‘ ๋™์ผํ•˜๊ฒŒ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ? 

@Override
public int hashCode()
{
   return 42;
}

์ด ์ฝ”๋“œ๋Š” ๋™์น˜์ธ ๋ชจ๋“  ๊ฐ์ฒด์—์„œ ๋˜‘๊ฐ™์€ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์ ๋ฒ•ํ•˜์ง€๋งŒ ๋ชจ๋“  ๊ฐ์ฒด์—๊ฒŒ ๋˜‘๊ฐ™์€ ๊ฐ’์„ ๋‚ด์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ํ•ด์‹œ ํ…Œ์ด๋ธ”์˜ ๋ฒ„ํ‚ท ํ•˜๋‚˜์— ๋‹ด๊ฒจ ๋งˆ์น˜ ์—ฐ๊ฑธ ๋ฆฌ์ŠคํŠธ LinkedList์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค. 

-> ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ํ‰๊ท  ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด O(1) ์ธ ํ•ด์‹œํ…Œ์ด๋ธ”์ด O(n) ์œผ๋กœ ๋А๋ ค์ ธ์„œ, ๊ฐ์ฒด๊ฐ€ ๋งŽ์•„์ง€๋ฉด ๋„์ €ํžˆ ์“ธ ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค. 

 

 

๐Ÿ“š ์„ธ๋ฒˆ์งธ ๊ทœ์•ฝ์—์„œ ๋‘ ๊ฐ์ฒด์— ๋Œ€ํ•œ equals๊ฐ€ ๋‹ค๋ฅด๋”๋ผ๋„, hashCode์˜ ๊ฐ’์€ ๊ฐ™์„ ์ˆ˜ ์žˆ๋‹ค๊ณ ๋Š” ํ–ˆ์ง€๋งŒ ์„ฑ๋Šฅ์ƒ ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค๊ณ  ํ–ˆ๋‹ค. ์ข‹์€ ํ•ด์‹œ ํ•จ์ˆ˜๋ผ๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค์— ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90