JiwonDev

.equals์™€ .hashCode()๋Š” ํ•ญ์ƒ ํ•จ๊ป˜ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์•ผํ•œ๋‹ค.

by JiwonDev

Object ๋ฉ”์„œ๋“œ์— ์žˆ๋Š” .hashCode() ๋ฉ”์„œ๋“œ๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“  ๊ฐ์ฒด๋งŒ์˜ ๊ณ ์œ ํ•œ ์ •์ˆ˜ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค. equals()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•  ๋•Œ์—๋Š” ๋ฐ˜๋“œ์‹œ hashCode()๋„ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋„๋ก ํ•จ๊ป˜ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์™œ ๊ทธ๋Ÿฐ์ง€ ์ฐจ๊ทผ์ฐจ๊ทผ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

Card a = new Card('ํŠธ๋Ÿผํ”„์นด๋“œ',10)
Card b = new Card('ํŠธ๋Ÿผํ”„์นด๋“œ',10)

a == b // a์™€ b๋Š” ๋‚ด์šฉ๋งŒ ๊ฐ™์„ ๋ฟ, ๋‹ค๋ฅธ ๊ฐ์ฒด๋ผ์„œ False๊ฐ€ ๋‚˜์˜จ๋‹ค.

a.equals(b) // ์ด ๊ฒฐ๊ณผ๊ฐ€ True ๋‚˜์˜ค๊ฒŒ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๋‹ค๋ฉด
a.hashCode() == b.hashCode() // ์ด ๊ฒฐ๊ณผ๋„ True๊ฐ€ ๋‚˜์˜ค๋„๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์•ผ ํ•œ๋‹ค.

 


# ๋™๋“ฑ์„ฑ(equality)๊ณผ ๋™์ผ์„ฑ(identity)

๋™์ผ์„ฑ์€ ์™„์ „ํžˆ ๊ฐ™์€ ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ณ , ๋™๋“ฑ์„ฑ์€ ๋‹ค๋ฅธ ๊ฐ์ฒด์ด์ง€๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ’(์ •๋ณด)๊ฐ€ ๊ฐ™์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

๋™์ผํ•˜๋‹ค์˜ ๊ฒฝ์šฐ == ์—ฐ์‚ฐ์ž๋กœ ํ‘œ์‹œ๋˜๊ณ , ๋™๋“ฑํ•˜๋‹ค์˜ ๊ฒฝ์šฐ equals ์—ฐ์‚ฐ์ž๋กœ ๋น„๊ตํ•œ๋‹ค. 

์ฆ‰ ๊ฐ์ฒด ๊ฐ„ == ์—ฐ์‚ฐ์ž๋Š” ์ฃผ์†Œ๊ฐ’์˜ ๋น„๊ต, equals๋Š” ๋‚ด์šฉ์˜ ๋น„๊ต๋กœ ์‚ฌ์šฉํ•œ๋‹ค.


#  == ์—ฐ์‚ฐ

( == ) ์—ฐ์‚ฐ์€ ๊ฐ’ ์ž์ฒด๋ฅผ ๋น„๊ตํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค. ๋ ˆํผ๋Ÿฐ์Šค ํƒ€์ž…์ธ ๊ฒฝ์šฐ ๋ณ€์ˆ˜์—๋Š” ๊ฐ’์ด ์•„๋‹Œ ์‹ฌ๋ณผ์ด ๋“ค์–ด๊ฐ€์žˆ๊ธฐ์— ๋™๋“ฑ์„ฑ์ด ์•„๋‹Œ ๋™์ผ์„ฑ์„ ๋น„๊ตํ•œ๋‹ค.

 

์‚ฌ์‹ค ์ž๋ฐ”์—์„œ๋Š” int, double ๊ฐ™์€ ๊ธฐ๋ณธํ˜• ํƒ€์ž…๋„ ๋ ˆํผ๋Ÿฐ์Šค ํƒ€์ž…์œผ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ๋ ˆํผ๋Ÿฐ์Šค๋กœ ๋งŒ๋“ค๊ณ  Constant Pool์— ์‹ค์ œ ๊ฐ’์„ ๋„ฃ์–ด๋‘๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒํ•˜๋ฉด ์ƒ์ˆ˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Constant Pool ์•ˆ์— ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋งŒ๋“ค์–ด ์ตœ์ ํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ƒ์ˆ˜ ๊ฐ’์ด ์•„๋‹Œ ์ƒ์ˆ˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋น„๊ตํ•œ๋‹ค ํ•˜๋”๋ผ๋„ ( == )๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค. ์–ด์ฐจํ”ผ ๊ฐ™์€ ์ƒ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ์— ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋น„๊ตํ•ด๋„ ๊ฐ’์ด ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

clas Person { ... } 

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("kim");
        Person person2 = new Person(new String("kim"));
        Person person3 = person2;
        
        // ์ฐธ์กฐ ๊ฐ’์ด ๊ฐ€์ง„ ํฌ์ธํ„ฐ ์ฃผ์†Œ๋ฅผ ๋น„๊ตํ•œ๋‹ค.
        // person1 == person2 ๋Š” false
        // person2 == person3 ๋Š” true
    }
}

๋Ÿฐํƒ€์ž„์— ์ƒ์„ฑ๋œ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ.

๊ทธ๋ ‡๋‹ค๋ฉด ๋™์ผ์„ฑ์ด ์•„๋‹Œ ๋™๋“ฑ์„ฑ, ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ๊ฐ’์„ ๋น„๊ตํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ? ์ œ์ผ ์ฒ˜์Œ์— ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ, ์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•ด๋ผ๊ณ  Object.equals() ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

 


# .equlas()

์ฐธ๊ณ ๋กœ Object.equals() ์˜ ์›ํ˜•์€ ( == ) ์—ฐ์‚ฐ์œผ๋กœ ๋งŒ๋“ค์–ด์ ธ์žˆ๋‹ค. ์ฆ‰ ๊ฐ์ฒด์˜ ์ฃผ์†Œ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค

    // Object.equals์˜ ์›ํ˜•.
    public boolean equals(Object obj) {
        return (this == obj);
    }

 

equlas๋Š” ๋™๋“ฑ์„ฑ(equality)๋ฅผ ๋น„๊ตํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์›ํ˜•์„ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ Object ๊ฐ์ฒด๊ฐ€ ๊ฐ์ฒด์˜ ๊ฐ’์„ ๋ง‰ ๋ถ„์„ํ•ด์„œ ์ž๋™์œผ๋กœ ๋น„๊ตํ•ด์ฃผ๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ equals() ๊ฐ์ฒด๋ฅผ ์ƒ์†ํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์—ฌ์•ผํ•œ๋‹ค.

 


# String.equals()

String๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹จ์ˆœํžˆ ์ฃผ์†Œ๊ฐ’ ๋น„๊ต(==)๋ฅผ ํ•˜๊ฒŒ๋˜๋ฉด Constant pool์— ์žˆ๋Š” ์ƒ์ˆ˜ ์ŠคํŠธ๋ง์€ ์ •์ƒ ๋น„๊ต๊ฐ€ ๋˜๊ฒ ์ง€๋งŒ, new๋ฅผ ์ด์šฉํ•˜์—ฌ String ๊ฐ์ฒด๋ฅผ ๋น„๊ตํ•˜๋ฉด ์ฃผ์†Œ๊ฐ’์ด ๋‹ค๋ฅด๊ธฐ์— ์ •์ƒ ๋น„๊ต๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

๊ทธ๋ž˜์„œ String ๊ตฌํ˜„๋ถ€๋ฅผ ์‚ดํŽด๋ณด๋ฉด Object.equals()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์—ฌ ์ƒˆ๋กญ๊ฒŒ ์ •์˜ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. String.equals() ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ๋ฌธ์ž์—ด์„ ํ•œ ๊ธ€์ž์”ฉ ๋น„๊ตํ•˜์—ฌ ๋™์ผํ•˜๋‹ค๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋˜์–ด์žˆ๋‹ค.

String.equals() ์˜ ๊ตฌํ˜„ ๋‚ด์šฉ.

 

# ๊ฐ์ฒด์˜ hashCode()

๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ hashCode๋Š” ์ผ์ข…์˜ ๊ฐ์ฒด ์ง€๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ ๊ฐ์ฒด์˜ ๊ฐ’์„ ๋Œ€ํ‘œํ•˜๋Š” ๊ฑด๋ฐ, ๊ธฐ๋ณธ ๊ตฌํ˜„์€ ๊ฐ์ฒด์˜ ์ฃผ์†Œ์— hashํ•จ์ˆ˜๋ฅผ ์ ์šฉ์‹œ์ผœ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฆ„์ด ํ•ด์‰ฌ์ฝ”๋“œ. (์ฃผ์†Œ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์™€ ์“ฐ๋Š”๊ฑด ์•„๋‹ˆ๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹๊ฒŒ ๋ณ€ํ˜•ํ•œ๋‹ค.)

* ์ฐธ๊ณ ๋กœ Object.hashCode()๋Š” native ๋ฉ”์„œ๋“œ์ด๋‹ค.

๋”๋ณด๊ธฐ

์ด๋ฅผ ์‰ฝ๊ฒŒ๋งํ•˜๋ฉด, ์ž๋ฐ” ์ฝ”๋“œ์ƒ์—์„œ๋Š” .hashCode() ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์ ํ˜€์žˆ์„ ๋ฟ ๊ตฌํ˜„์ฒด๋Š” ์—†๋‹ค.

public class Object {
	public native int hashCode(); // ์ธํ„ฐํŽ˜์ด์Šค๋งˆ๋ƒฅ ๊ตฌํ˜„๋ถ€๊ฐ€ ์—†์Œ.
}

์ด๋ ‡๊ฒŒ native ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์™ธ๋ถ€์—์„œ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ์ปดํŒŒ์ผ๋œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ž๋ฐ”์˜ hashCode() ๋ฉ”์„œ๋“œ๋Š” ์šด์˜์ฒด์ œ์— ์ž‘์„ฑ๋˜์–ด์žˆ๋Š” ๋ฉ”์„œ๋“œ(๋ณดํ†ต C์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค.)๋ฅผ ์ด์šฉํ•ด hashCode ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ•œ๋‹ค.

์ฐธ๊ณ ๋กœ ์ž๋ฐ”์—์„œ ์ž๋ฐ”๊ฐ€ ์•„๋‹Œ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” JNI๋ผ๋Š” ๊ธฐ์ˆ ์ด ์žˆ๋‹ค. ์ด๋Š” ๊ถ๊ธˆํ•˜๋ฉด ์ง์ ‘ ์ฐพ์•„๋ณด์ž.

์ฐธ๊ณ ๋กœ ๊ฐ™์€ ํ•ด์‹œ๊ฐ’์ด ๋‚˜์˜ค๋Š” ๊ฒƒ์„ Hash Collisions(ํ•ด์‹œ์ถฉ๋Œ) ์ด๋ผํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ ์˜ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ LinkedList๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ํ•œ๋‹ค

clas Person { ... } 

public class Main {
    public static void main(String[] args) {
        Person person1 = new Person("kim");
        Person person2 = new Person(new String("kim"));
        Person person3 = person2;
        System.out.println("person1.hashCode() = " + person1.hashCode());
        System.out.println("person2.hashCode() = " + person2.hashCode());
        System.out.println("person3.hashCode() = " + person3.hashCode());
        
        // person1.hashCode() = 1349414238
        // person2.hashCode() = 321142942
        // person3.hashCode() = 321142942 ์ฃผ์†Œ๊ฐ€ ๊ฐ™์œผ๋ฉด hashCode๋„ ๊ฐ™๋‹ค.
    }
}

 


# String์˜ hashCode()

ํ•˜์ง€๋งŒ String์˜ ๊ฒฝ์šฐ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค. String ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ์ฃผ์†Œ๊ฐ’์ด ์•„๋‹ˆ๋ผ ๋ฌธ์ž์—ด์—์„œ ํ•œ ๊ธ€์ž์”ฉ ๊ฐ€์ ธ์™€ ๋ณ€ํ™˜ํ•˜์—ฌ String ๊ฐ์ฒด๊ฐ„์˜ ๋™์ผ์„ฑ์„ ๋น„๊ตํ•˜๋Š” hashCode()๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ฆ‰ ์ฃผ์†Œ๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž์—ด ๋‚ด์šฉ ์ž์ฒด๋ฅผ ๋น„๊ต(=๋™๋“ฑ์„ฑ ๋น„๊ต)ํ•˜๋Š” hashCode๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์…ˆ.

 

์ฐธ๊ณ ๋กœ ์ž๋ฐ”๋Š” 32๋น„ํŠธ ์šด์˜์ฒด์ œ๋งŒ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐœ๋ฐœ๋œ ์–ธ์–ด๋ผ 32๋น„ํŠธ ์ฃผ์†Œ๊ฐ’์„ ์ด์šฉํ•ด์„œ ํ•ด์‰ฌํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค. 64๋น„ํŠธ ์šด์˜์ฒด์ œ์˜ ๊ฒฝ์šฐ ์ฃผ์†Œ๊ฐ’์— ์ ˆ๋ฐ˜๋งŒ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ตœ๋Œ€ํ•œ ๊ฒน์น˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค์—ˆ์–ด๋„ ์ •๋ง ์ •๋ง ๋‚ฎ์€ ํ™•๋ฅ ๋กœ ๊ฐ™์€ ์ฃผ์†Œ๊ฐ’์ด 2๊ฐœ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค๋Š”๊ฑธ ์ƒ์‹์œผ๋กœ ์•Œ๊ณ ๋งŒ ์žˆ์ž. ์ฃผ์†Œ๊ฐ’์ด ๊ฐ™์œผ๋ฉด ๋‹น์—ฐํžˆ ํ•ด์‰ฌ์ฝ”๋“œ์˜ ๊ฐ’๋„ ๊ฐ™๋‹ค. (๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค์ƒ ์ผ์–ด๋‚  ํ™•๋ฅ ์ด 0์— ๊ฐ€๊น๊ณ  64๋น„ํŠธ๋กœ ๋ฐ”๊ฟจ์„ ๋•Œ ์„ฑ๋Šฅ์ด ํ•˜๋ฝํ•ด์„œ ๊ทธ๋Œ€๋กœ 32๋น„ํŠธ ์ฃผ์†Œ์ฒด๊ณ„๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.)

์ฐธ๊ณ ๋กœ hashCode๋ฅผ ๋งŒ๋“œ๋Š” ํ•ด์‰ฌํ•จ์ˆ˜ ์ˆ˜์‹์„ ๋งŒ๋“ค ๋•Œ ์ˆซ์ž 31์„ ์ž์ฃผ ์‚ฌ์šฉํ•œ๋‹ค.

๋”๋ณด๊ธฐ

๊ทธ ์ด์œ ๋Š” ๋งŒ๋“ค์–ด์ง„ hashCode๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์—ฐ์‚ฐ ์„ฑ๋Šฅ์„ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•จ์ธ๋ฐ, ๋ฌด๊ฑฐ์šด ๊ณฑ์…ˆ ์—ฐ์‚ฐ์„ ๋บ„์…ˆ์œผ๋กœ ๋ฐ”๊ฟ” ์ตœ์ ํ™” ํ•˜๊ธฐ ์œ„ํ•ด ์ ๋‹นํ•œ ์ˆซ์ž๋ฅผ ๊ณฑํ•ด ๋น„ํŠธ๋ฅผ ์™ผ์ชฝ์œผ๋กœ ์‰ฌํ”„ํŠธ ํ•ด์•ผํ•˜๋Š”๋ฐ 31์ด ์†Œ์ˆ˜ + ํ™€์ˆ˜ + 2์˜ ๋ฐฐ์ˆ˜($2^5 -1)$ ์ธ ์™„๋ฒฝํ•œ ์ˆซ์ž์ด๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

 

- 2์˜ ๋ฐฐ์ˆ˜๋Š” ์• ์ดˆ์— ๋ชฉ์ ์ด ๋น„ํŠธ ์‰ฌํ”„ํŠธ (00011 -> 01100)๋ฅผ ์ด์šฉํ•œ ํ•ด์‰ฌ์ฝ”๋“œ์˜ ์—ฐ์‚ฐ ์ตœ์ ํ™”๋ผ์„œ ๊ทธ๋ ‡๋‹ค.

 

- ๋ถˆํŽธํ•˜๊ฒŒ 2์˜ ๋ฐฐ์ˆ˜(์ง์ˆ˜)๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  -1 ํ•ด์„œ ํ™€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฑด ํ•œ์ชฝ์ด 0์œผ๋กœ ๊ณ ์ •๋˜๋Š”๊ฑธ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค. ํ•ด์‹œ์ฝ”๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ ์ง์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด ์—ฐ์‚ฐํ•  ๋•Œ ๋งˆ๋‹ค ์˜ค๋ฅธ์ชฝ์— 0์ด ๊ณ„์†ํ•ด์„œ ์ถ”๊ฐ€๋˜์–ด (5120000000) ๊ฐ™์€ ๊ฐ’์ด ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 
- ๋น„ํŠธ ์‰ฌํ”„ํŠธ์— ๊ตณ์ด ์†Œ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฑด..์‚ฌ์‹ค ๋ณ„ ์ด์œ ๊ฐ€ ์—†๋‹ค. ๊ทธ๋ƒฅ ์†Œ์ˆ˜๋ฅผ ์“ฐ๋ฉด ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์ข‹์„๊ฑฐ ๊ฐ™๋‹ค๋Š” ๋ฏธ์‹  ๋•Œ๋ฌธ์ด๋‹ค. (์‹ค์ œ JVM ๊ฐœ๋ฐœ์ž๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ง์ด๋‹ค.)

 


# equals()์™€ hashcode()์˜ ๋™์ž‘์€ ๊ฐ™์•„์•ผ ํ•œ๋‹ค.

์ด๋Š” ์ผ์ข…์˜ ๊ทœ์น™์ด๋‹ค. ๋ฌผ๋ก  ์ง€ํ‚ค์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ”„๋กœ๊ทธ๋žจ์ด ๋ฉˆ์ถ”๊ฑฐ๋‚˜ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์•ผํ•˜๋Š” ์ด์œ ๋Š” ์ฝ”๋“œ์˜ ํ™•์žฅ์„ฑ ๊ฐ™์€ ์ถ”์ƒ์ ์ธ ์ด์œ ๋„ ์žˆ๊ฒ ์ง€๋งŒ ์ œ์ผ ์ค‘์š”ํ•œ๊ฑด ์ž๋ฐ”์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ hashCode()์™€ equals()๋ฅผ ๋‘˜ ๋‹ค ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” hashCode() ์™€ equals()๋ฅผ ์‚ดํŽด๋ณด์ž. ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ HashMap์—์„œ ํ‚ค ๊ฐ’์„ ์ƒˆ๋กœ ์ž…๋ ฅํ•  ๋•Œ, ์ค‘๋ณต๋œ ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ๋น„๊ตํ•˜๋Š” ์—ฐ์‚ฐ์„ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ๋‹ค.

  • hashCode()
    ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์„œ ๋ฆฌํ„ด๋œ hashCode() ๊ฐ’์ด ๊ฐ™์€์ง€ ๋ณธ๋‹ค. ๋งŒ์•ฝ ๋‹ค๋ฅด๋‹ค๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ํŒ๋‹จํ•œ๋‹ค.
  • hashCode() -> equals()
    hashCode์˜ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด equals(~)๋กœ ๋‹ค์‹œ ๋น„๊ตํ•œ๋‹ค. ์ด ๋‘ ๊ฐœ๊ฐ€ ๋ชจ๋‘ ๋งž์•„์•ผ ๋™๋“ฑํ•œ ๊ฐ์ฒด๋กœ ํŒ๋‹จํ•œ๋‹ค.
    ๋งŒ์•ฝ hashCode์˜ ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด ๋น„๊ต ์—ฐ์‚ฐ ์ž์ฒด๋ฅผ ํ•˜์ง€์•Š์Œ์„ ์œ ์˜ํ•˜์ž

๋งŒ์•ฝ equals()๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ( == ) ๋ฅผ ์ด์šฉํ•ด์„œ ๋™์ผ์„ฑ ๋น„๊ต๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ์ž‘์—…์— ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด ๊ฐ์ฒด์˜ ๋น„๊ต๋ฅผ ์œ„ํ•ด equals()๋ฅผ ์ˆ˜์ •ํ–ˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ hashCode() ๋น„๊ต๋„ ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋„๋ก ํ•ด์‹œํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ด์•ผํ•œ๋‹ค.

 

๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€์•Š๋Š”๋‹ค๋ฉด ์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๋Œ€๋กœ๋œ ๋น„๊ต ๋™์ž‘์„ ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋œ๋‹ค.


# equals๋ฅผ ์žฌ์ •์˜ ํ•˜๋ ค๊ฑฐ๋“  hashCode๋„ ์žฌ์ •์˜ ํ•ด์•ผํ•œ๋‹ค.

๊ฒฐ๋ก ์ด๋‹ค.

  • ๋™์ผ์„ฑ(==)์ด ์•„๋‹Œ ๋™๋“ฑ์„ฑ(.equals)์„ ๋น„๊ตํ•˜๋ ค๋ฉด Object.equals()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•ด์•ผํ•œ๋‹ค.
  • ๋‹จ, equals()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ hashCode() ๋น„๊ต๋„ ๋™์ผํ•œ ๋™์ž‘์„ ํ•˜๋„๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•œ๋‹ค.
  • ์ฆ‰ [ A.equals(B) ]๊ฐ€ True๋ผ๋ฉด [ A.hashCode() == B.hashCode ]๋„ True๊ฐ€ ๋˜๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
Card a = new Card('ํŠธ๋Ÿผํ”„์นด๋“œ',10)
Card b = new Card('ํŠธ๋Ÿผํ”„์นด๋“œ',10)

a == b // a์™€ b๋Š” ๋‚ด์šฉ๋งŒ ๊ฐ™์„ ๋ฟ, ๋‹ค๋ฅธ ๊ฐ์ฒด๋ผ์„œ False๊ฐ€ ๋‚˜์˜จ๋‹ค.

a.equals(b) // ์ด ๊ฒฐ๊ณผ๊ฐ€ True ๋‚˜์˜ค๊ฒŒ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๋‹ค๋ฉด
a.hashCode() == b.hashCode() // ์ด ๊ฒฐ๊ณผ๋„ True๊ฐ€ ๋‚˜์˜ค๋„๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์•ผ ํ•œ๋‹ค.

 

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

    @Override
    public boolean equals(Object obj) {
        // equals๋ฅผ kind ์™€ number๋ฅผ ์ด์šฉํ•˜์—ฌ ๋น„๊ตํ•˜๋„๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์˜€๋‹ค.
        if (!(obj) instanceof Card) {
            return false;
        }
        
        Card c = (Card)obj;
        return this.kind.equals(c.kind) && this.number == c.number
    }

    @Override
    public int hashCode() {
        // ๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ hashCode()๋„ kind์™€ number๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค.
        // ์ฆ‰ ํ•ด์‹œ์ฝ”๋“œ ๋น„๊ต๊ฐ€ equals์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. 
        return Object.hash(kind, number)
    }

hashCode๋ฅผ ์ž˜ ๋งŒ๋“œ๋Š” ๊ฟ€ํŒ(Effetive Java 3ํŒ)

 

java.lang.Object .hashCode ๋ฉ”์†Œ๋“œ

 

johngrib.github.io

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ