ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ์•„์ดํ…œ11. equals๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๊ฑฐ๋“  hashCode๋„ ์žฌ์ •์˜ํ•˜๋ผ
    DevBook/Effective Java 2023. 5. 7. 12:57

    ๐Ÿ“์ƒํ™ฉ

    • equals๋ฅผ ์žฌ์ •์˜ํ•œ ํด๋ž˜์Šค ๋ชจ๋‘์—์„œ hashCode๋„ ์žฌ์ •์˜ํ•ด์•ผ ํ•จ

     

    ์ด์œ 

    • hashCode ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์–ด๊ธฐ๊ฒŒ ๋˜์–ด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ HashMap์ด๋‚˜ HashSet ๊ฐ™์€ ์ปฌ๋ ‰์…˜์˜ ์›์†Œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋จ
    • ๊ทœ์•ฝ

     

    ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„

    • hashCode๋ฅผ ์ž˜๋ชป ์žฌ์ •์˜ํ–ˆ์„ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์กฐํ•ญ์€ ๋‘ ๋ฒˆ์งธ์ž„
    • hashCode๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋…ผ๋ฆฌ์  ๋™์น˜์ธ ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋‘ ๋ฒˆ์งธ ๊ทœ์•ฝ์„ ์ง€ํ‚ค์ง€ ๋ชปํ•จ --> ์ฆ‰, ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐ™์€ ๊ฐ์ฒด๋Š” ๊ฐ™์€ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•จ

    ์˜ˆ์‹œ

    Map<PhoneNumber, String> map = new HashMap<>();
    map.put(new PhoneNumber(010, 1234, 5678), "java");
    
    //PhoneNumber ํด๋ž˜์Šค์˜ equals๋ฅผ ์žฌ์ •์˜ํ–ˆ๋Š”๋ฐ hashCode๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
    map.get(new PhoneNumber(010, 1234, 5678)); //์˜ˆ์ƒ ๊ฐ’ : java, ์‹ค์ œ ๊ฐ’ : null
    • PhoneNumber ํด๋ž˜์Šค์˜ hashCode๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋…ผ๋ฆฌ์  ๋™์น˜์ธ ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— get ๋ฉ”์„œ๋“œ๋Š” ์—‰๋šฑํ•œ ํ•ด์‹œ ๋ฒ„ํ‚ท์— ๊ฐ€์„œ ๊ฐ์ฒด๋ฅผ ์ฐพ์œผ๋ ค ํ•จ
    • ๋งŒ์•ฝ ๋‘ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ™์€ ๋ฒ„ํ‚ท์— ๋‹ด์•˜๋”๋ผ๋„ get ๋ฉ”์„œ๋“œ๋Š” ์—ฌ์ „ํžˆ null์„ ๋ฐ˜ํ™˜ํ•จ
      • HashMap์€ ํ•ด์‹œ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฅธ ์—”ํŠธ๋ฆฌ๋ผ๋ฆฌ๋Š” ๋™์น˜์„ฑ ๋น„๊ต๋ฅผ ์‹œ๋„์กฐ์ฐจ ํ•˜์ง€ ์•Š๋„๋ก ์ตœ์ ํ™”๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž„

     

    => ์ด ๋ฌธ์ œ๋Š” ์ ์ ˆํ•œ hashCode ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐ๋จ!

     

    ๐Ÿ“๋ฐฉ๋ฒ•

    ์˜ฌ๋ฐ”๋ฅธ hashCode ๋ฉ”์„œ๋“œ๋Š” ์–ด๋–ค ๋ชจ์Šต์ด์–ด์•ผ ํ• ๊นŒ?

     

    1)

    ์ฝ”๋“œ11-1 ์ตœ์•…์˜ hashCode ๊ตฌํ˜„ - ์‚ฌ์šฉ ๊ธˆ์ง€!

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

    ๋ฌธ์ œ์ 

    • ๋ชจ๋“  ๊ฐ์ฒด์—์„œ ๋˜‘๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ํ•ด์‹œํ…Œ์ด๋ธ”์˜ ๋™์ผํ•œ ๋ฒ„ํ‚ท์— ๋‹ด๊ฒจ ๋งˆ์น˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์ฒ˜๋Ÿผ ๋™์ž‘ํ•จ
    • ํ‰๊ท  ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด O(1)์ธ ํ•ด์‹œํ…Œ์ด๋ธ”์ด O(n)์œผ๋กœ ๋Š๋ ค์ง

     

    2)

    • ์ข‹์€ ํ•ด์‹œ ํ•จ์ˆ˜๋ผ๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค์— ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•จ
    • ์ด์ƒ์ ์ธ ํ•ด์‹œ ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ ์„œ๋กœ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋“ค์„ 32๋น„ํŠธ ์ •์ˆ˜ ๋ฒ”์œ„์— ๊ท ์ผํ•˜๊ฒŒ ๋ถ„๋ฐฐํ•ด์•ผ ํ•จ
    • ์ด์ƒ์„ ์™„๋ฒฝํžˆ ์‹คํ˜„ํ•˜๊ธฐ๋Š” ์–ด๋ ต์ง€๋งŒ ๋น„์Šทํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฐ„๋‹จํ•œ ์š”๋ น์„ ๋‹ค์Œ๊ณผ ๊ฐ™์Œ

     

    ํ•ด๋‹น ์š”๋ น์„ ์ ์šฉํ•œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Œ

    ์ฝ”๋“œ 11-2 ์ „ํ˜•์ ์ธ hashCode ๋ฉ”์„œ๋“œ

    @Override
    public int hashCode() {
        int result = Short.hashCode(areaCode);
        result = 31 * result + Short.hashCode(prefix);
        result = 31 * result + Short.hashCode(lineNum);
        return result;
    }

     

    ์ถ”๊ฐ€

    • ํ•ด์‹œ ์ถฉ๋Œ์ด ๋” ์ ์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๊ตฌ์•„๋ฐ”์˜ com.google.common.hash.Hashing ์ฐธ๊ณ 

     

    3)

    • Objects ํด๋ž˜์Šค๋Š” ์ž„์˜์˜ ๊ฐœ์ˆ˜๋งŒํผ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๊ณ„์‚ฐํ•ด์ฃผ๋Š” ์ •์  ๋ฉ”์„œ๋“œ์ธ hash๋ฅผ ์ œ๊ณตํ•จ
    • ํ•˜์ง€๋งŒ hash๋Š” ์†๋„๊ฐ€ 2) ๋ณด๋‹ค ๋” ๋Š๋ฆผ
      • ์ž…๋ ฅ ์ธ์ˆ˜๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง€๊ณ , ์ž…๋ ฅ ์ค‘ ๊ธฐ๋ณธ ํƒ€์ž…์ด ์žˆ๋‹ค๋ฉด ๋ฐ•์‹ฑ๊ณผ ์–ธ๋ฐ•์‹ฑ์„ ๊ฑฐ์ณ์•ผ ํ•จ
      • ๋”ฐ๋ผ์„œ hash ๋ฉ”์„œ๋“œ๋Š” ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•˜์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜์ž

     

    ์ฝ”๋“œ 11-3 ํ•œ ์ค„์งœ๋ฆฌ hashCode ๋ฉ”์„œ๋“œ - ์„ฑ๋Šฅ์ด ์‚ด์ง ์•„์‰ฌ์›€

    @Override
    public int hashCode() {
        return Objects.hash(lineNum, prefix, areaCode);
    }

     

    4)

    • ํด๋ž˜์Šค๊ฐ€ ๋ถˆ๋ณ€์ด๊ณ  ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋น„์šฉ์ด ํฌ๋‹ค๋ฉด, ๋งค๋ฒˆ ์ƒˆ๋กœ ๊ณ„์‚ฐํ•˜๊ธฐ๋ณด๋‹ค๋Š” ์บ์‹ฑํ•˜๋Š” ๋ฐฉ์‹์„ ๊ณ ๋ คํ•ด์•ผ ํ•จ
    • ๊ฒฝ์šฐ์— ๋”ฐ๋ฅธ ๋ฐฉ์‹
      • ํ•ด๋‹น ํƒ€์ž…์˜ ๊ฐ์ฒด๊ฐ€ ์ฃผ๋กœ ํ•ด์‹œ์˜ ํ‚ค๋กœ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด? --> ์ธ์Šคํ„ด์Šค๊ฐ€ ๋งŒ๋“ค์–ด์งˆ ๋•Œ ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๊ณ„์‚ฐํ•ด๋‘ฌ์•ผ ํ•จ
      • ํ•ด์‹œ์˜ ํ‚ค๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด? --> hashCode๊ฐ€ ์ฒ˜์Œ ๋ถˆ๋ฆด ๋•Œ ๊ณ„์‚ฐํ•˜๋Š” ์ง€์—ฐ ์ดˆ๊ธฐํ™” ์ „๋žต ๊ณ ๋ คํ•ด์•ผ ํ•จ
        • ํ•„๋“œ๋ฅผ ์ง€์—ฐ ์ดˆ๊ธฐํ™”ํ•˜๋ ค๋ฉด ๊ทธ ํด๋ž˜์Šค๋ฅผ thread-safeํ•˜๊ฒŒ ๋งŒ๋“ค๋„๋ก ์‹ ๊ฒฝ์จ์•ผ ํ•จ (์•„์ดํ…œ 83)

     

    ์ฝ”๋“œ 11-4 ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ์ง€์—ฐ ์ดˆ๊ธฐํ™”ํ•˜๋Š” hashCode ๋ฉ”์„œ๋“œ - ์Šค๋ ˆ๋“œ ์•ˆ์ •์„ฑ๊นŒ์ง€ ๊ณ ๋ คํ•ด์•ผ ํ•จ

    private int hashCode; //์ž๋™์œผ๋กœ 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋จ
    
    @Override
    public int hashCode() {
        int result = hashCode;
        if (result == 0) {
        	result = Short.hashCode(areaCode);
            result = 31 * result + Short.hashCode(prefix);
            result = 31 * result + Short.hashCode(lineNum);
            hashCode = result;
        }
        return result;
    }

     

    ์ฃผ์˜

    1) ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํ•ด์‹œ์ฝ”๋“œ ๊ณ„์‚ฐํ•  ๋•Œ ํ•ต์‹ฌ ํ•„๋“œ๋ฅผ ์ƒ๋žตํ•˜๋ฉด ์•ˆ๋จ

    • ํ•ด์‹œ ํ’ˆ์งˆ์ด ๋‚˜๋น ์ ธ ํ•ด์‹œํ…Œ์ด๋ธ”์˜ ์„ฑ๋Šฅ์„ ์‹ฌ๊ฐํ•˜๊ฒŒ ๋–จ์–ด๋œจ๋ฆด ์ˆ˜ ์žˆ์Œ

    2) hashCode๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์˜ ์ƒ์„ฑ ๊ทœ์น™์„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ž์„ธํžˆ ๊ณตํ‘œํ•˜์ง€ ๋ง์ž

    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ด ๊ฐ’์— ์˜์ง€ํ•˜์ง€ ์•Š๊ฒŒ ๋˜๊ณ , ์ถ”ํ›„์— ๊ณ„์‚ฐ ๋ฐฉ์‹์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Œ

     

    ๐Ÿ“ํ•ต์‹ฌ ์ •๋ฆฌ

    • equals๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ๋Š” hashCode๋„ ๋ฐ˜๋“œ์‹œ ์žฌ์ •์˜ํ•ด์•ผ ํ•จ
    • ์žฌ์ •์˜ํ•œ hashCode๋Š” Object์˜ API ๋ฌธ์„œ์— ๊ธฐ์ˆ ๋œ ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ๋”ฐ๋ผ์•ผ ํ•˜๋ฉฐ, ์„œ๋กœ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ผ๋ฉด ๋˜๋„๋ก ํ•ด์‹œ์ฝ”๋“œ๋„ ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
    • AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ IDE๋“ค์—์„œ equals์™€ hashCode๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•จ

    ๋Œ“๊ธ€

Designed by Tistory.