๋งค์ผ๋ฉ์ผ ๋ฐฑ์๋ ์ง๋ฌธ์ ์ฐธ๊ณ ํด ๊ฐ์ธ์ ์ผ๋ก ํ์ตํ ๋ด์ฉ์ ์ ๋ฆฌํ์์ต๋๋ค.
์ค๋ฅ๊ฐ ์๋ค๋ฉด ์ธ์ ๋ ํผ๋๋ฐฑ ์ฃผ์๋ฉด ๋ฐ๋ก ๋ฐ์ํ๊ฒ ์ต๋๋ค..!
์์ํ๊ธฐ์ ์
JAVA๋ก ์ฝ๋ฉ์ ํ๋ค๋ณด๋ฉด ๊ฐ์ฒด๋ฅผ ๋น๊ตํด์ผ ํ๋ ์๊ฐ์ด ์ ๋ง ๋ง์๋ฐ ์ด ๋ '๋์ผ์ฑ'๊ณผ '๋๋ฑ์ฑ'์ด๋ผ๋ ๋ ๊ฐ๋ ์ ๋ช ํํ ์ดํดํ์ง ๋ชปํ๋ฉด, ์์ธกํ ์ ์๋ ๊ณณ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํด์ ๊ณ ์ํ ์ ์์
Java์์๋ ์ด ๋ ๊ฐ๋ ์ == ์ฐ์ฐ์์ equals() ๋ฉ์๋๋ก ๊ตฌ๋ถํจ
๋์ผ์ฑ(Identity)๊ณผ ๋๋ฑ์ฑ(Equality)
๋์ผ์ฑ
"๋ ๊ฐ์ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์์ ์์ ํ ๊ฐ์ ์กด์ฌ์ธ๊ฐ?" ๋ฅผ ์๋ฏธํจ
=> ์ฆ, ๋ ๋ณ์๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋์ผํ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋์ง๋ฅผ ํ์ธํ๋ ๊ฐ๋
๋๋ฑ์ฑ
"๋ ๊ฐ์ ๊ฐ์ฒด๊ฐ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์ ๋ด์ฉ(๊ฐ)์ ๊ฐ์ง๊ณ ์๋๊ฐ?" ๋ฅผ ์๋ฏธํจ
=> ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ค๋ฅด๋๋ผ๋, ๊ฐ์ฒด๊ฐ ๊ฐ์ง ํต์ฌ์ ์ธ ์์ฑ๊ฐ์ด ๊ฐ๋ค๋ฉด ๋๋ฑํ๋ค๊ณ ํ๋จํจ
๋์ผ์ฑ ๋น๊ต : == ์ฐ์ฐ์
== ์ฐ์ฐ์๋ ๋ ๋ณ์๊ฐ ์ฐธ์กฐํ๋ ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ์ ๋น๊ตํจ
๋ฐ๋ผ์, == ์ฐ์ฐ์ ๊ฒฐ๊ณผ๊ฐ true๋ผ๋ฉด, ๋ ๋ณ์๋ ์ ํํ ๋์ผํ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ค๋ ์๋ฏธ์
public class IdentityTest {
public static void main(String[] args) {
Apple apple1 = new Apple(100); // 1๋ฒ ์ฌ๊ณผ ๊ฐ์ฒด ์์ฑ
Apple apple2 = new Apple(100); // 2๋ฒ ์ฌ๊ณผ ๊ฐ์ฒด ์์ฑ (1๋ฒ๊ณผ ๋ด์ฉ์ ๊ฐ์ง๋ง ๋ค๋ฅธ ๊ฐ์ฒด)
Apple apple3 = apple1; // 3๋ฒ ์ฌ๊ณผ๋ 1๋ฒ ์ฌ๊ณผ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํด
// apple1๊ณผ apple2๋ ๋ด์ฉ์ ๊ฐ์ง๋ง, ์๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋น๋ ๋ณ๊ฐ์ ๊ฐ์ฒด์
๋๋ค.
System.out.println("apple1 == apple2: " + (apple1 == apple2)); // ๊ฒฐ๊ณผ: false
// apple3์ apple1์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ๋๊ฐ์ด ๊ฐ๋ฆฌํต๋๋ค.
System.out.println("apple1 == apple3: " + (apple1 == apple3)); // ๊ฒฐ๊ณผ: true
}
}
class Apple {
private final int weight;
public Apple(int weight) {
this.weight = weight;
}
// ... equals()์ hashCode()๋ ์ ์ ํ ์ดํด๋ด
๋๋ค.
}
๋งค์ผ๋ฉ์ผ์ ์์์ฝ๋๋ก ์ดํด๋ณด๋ฉด ์ ์ฝ๋์์ apple1๊ณผ apple2๋ ๋ฌด๊ฒ๊ฐ 100์ผ๋ก ๊ฐ์ง๋ง, new ํค์๋๋ฅผ ํตํด ๊ฐ๊ฐ ๋ ๋ฆฝ์ ์ธ ๊ฐ์ฒด๋ก ์์ฑ๋์์
=> ๋์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ค๋ฅด๋ฏ๋ก == ๋น๊ต ๊ฒฐ๊ณผ false์
๋ฐ๋ฉด, apple3์ apple1์ ์ฃผ์ ๊ฐ์ ๊ทธ๋๋ก ํ ๋น๋ฐ์๊ธฐ ๋๋ฌธ์ == ๋น๊ต ๊ฒฐ๊ณผ๊ฐ true๊ฐ ๋จ
๋๋ฑ์ฑ ๋น๊ต : euqals() ๋ฉ์๋
equals() ๋ฉ์๋๋ ๋ ๊ฐ์ฒด์ ๋ด์ฉ์ด ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์์ง๋ฅผ ๋น๊ตํจ
ํ์ง๋ง, ์ฌ๊ธฐ์๋ ํจ์ ์ด ์๋๋ฐ ๋ฐ๋ก Object ํด๋์ค์ equals() ๋ฉ์๋ ๊ธฐ๋ณธ ๋์ ๋ฐฉ์์
๋ชจ๋ ์๋ฐ ํด๋์ค๋ ๋ช ์ํ์ง ์์๋ Object ํด๋์ค๋ฅผ ์์๋ฐ์
// Object.java
public class Object {
// ...
public boolean equals(Object obj) {
return (this == obj); // ๊ธฐ๋ณธ์ ์ผ๋ก == ์ฐ์ฐ๊ณผ ๋์ผํ๊ฒ ๋์ํ๋ค!
}
// ...
}
Object ํด๋์ค์ ์ ์๋ equals() ๋ฉ์๋๋ ์์ ๊ฐ์๋ฐ ๊ธฐ๋ณธ ๊ตฌํ์ == ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ ๋์ผ์ฑ ๋น๊ต์ธ ๊ฒ์ ์ ์ ์์
๋ฐ๋ผ์, ์์์ ์ง์ ๋ง๋ Apple ํด๋์ค์์ equals()๋ฅผ ์ฌ์ ์(Overriding)ํ์ง ์์ผ๋ฉด, apple1.equals(apple2)๋ apple1 == apple2 ์ ๋๊ฐ์ด ๋์ํ์ฌ false๋ฅผ ๋ฐํํ๊ฒ๋จ
import java.util.Objects;
public class Apple {
private final int weight;
public Apple(int weight) {
this.weight = weight;
}
// Object์ equals() ๋ฉ์๋๋ฅผ ์ฌ์ ์
@Override
public boolean equals(Object o) {
// 1. ๋์ผ์ฑ ์ฒดํฌ: ๊ฐ์ ๊ฐ์ฒด๋ฉด ๋ฌด์กฐ๊ฑด true (์ฑ๋ฅ ์ต์ ํ)
if (this == o) return true;
// 2. null ์ฒดํฌ ๋ฐ ํด๋์ค ํ์
์ฒดํฌ: ๋น๊ต ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ false
if (o == null || getClass() != o.getClass()) return false;
// 3. ํ ๋ณํ ํ ๋ด์ฉ ๋น๊ต: ์ค์ ํ๋ ๊ฐ์ ๋น๊ตํ์ฌ ๋๋ฑ์ฑ์ ํ๋จ
Apple apple = (Apple) o;
return weight == apple.weight;
}
// equals๋ฅผ ์ฌ์ ์ํ๋ค๋ฉด, ๋ฐ๋์ hashCode๋ ํจ๊ป ์ฌ์ ์ํด์ผ ํฉ๋๋ค!
@Override
public int hashCode() {
return Objects.hash(weight);
}
public static void main(String[] args) {
Apple apple = new Apple(100);
Apple anotherApple = new Apple(100);
// ์ฌ์ ์๋ equals()๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ ์๋ '๋ฌด๊ฒ(weight)'๋ฅผ ๋น๊ตํฉ๋๋ค.
System.out.println(apple.equals(anotherApple)); // ๊ฒฐ๊ณผ: true
}
}
๊ฐ์ฒด์ ๋ ผ๋ฆฌ์ ๋ด์ฉ์ ๋น๊ตํ๊ณ ์ถ๋ค๋ฉด, ์ ์ฝ๋์ฒ๋ผ equals() ๋ฉ์๋๋ฅผ ํด๋์ค์ ๋ชฉ์ ์ ๋ง๊ฒ ์ฌ์ ์ํด์ผํจ
=> ์ฌ๊ธฐ์๋ '๋ ์ฌ๊ณผ๋ ๋ฌด์ ๊ฐ ๊ฐ์ผ๋ฉด ๋๋ฑํ๋ค' ๋ผ๋ ๊ท์น์ ์ ์ฉํ์์
equals()๋ฅผ ์์ ๊ฐ์ด ์ฌ์ ์ํจ์ผ๋ก์จ, ์ด์ apple๊ณผ anotherApple์ ๋น๋ก ๋ค๋ฅธ ๊ฐ์ฒด์ผ์ง๋ผ๋ '๋ฌด๊ฒ๊ฐ ๊ฐ๋ค'๋ ๋ ผ๋ฆฌ์ ๊ธฐ์ค์ ๋ฐ๋ผ ๋๋ฑํ๋ค๊ณ ํ๋จํ ์ ์์
equals()๋ฅผ ์ฌ์ ์ํ๋ค๋ฉด, ๋ฐ๋์ hashCode()๋ ํจ๊ป ์ฌ์ ์ ํด์ผํจ
=> Java์์ equals()์ hashCode()์ ๊ท์ฝ์ด ์์
1. equals() ๋น๊ต ๊ฒฐ๊ณผ๊ฐ true์ธ ๋ ๊ฐ์ฒด๋ ๋ฐ๋์ ๋์ผํ hashCode() ๊ฐ์ ๋ฐํํด์ผ ํ๋ค
2. hashCode()๊ฐ ๋์ผํ ๋ ๊ฐ์ฒด๋ผ๊ณ ํด์ equals() ๋น๊ต ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋์ true์ผ ํ์๋ ์๋ค.
=> hashCode()๋ ๋ณดํต int ๊ฐ์ ๋ฐํํ๋ฏ๋ก int ๊ฐ์ ๋ฒ์๊ฐ ๋์ด๊ฐ๋ ๊ฐ์ฒด์ ์๋ฅผ ๋ค๋ฃจ๊ฒ๋๋ฉด ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ผ๋ ๋์ผํ ํด์์ฝ๋ ๊ฐ์ ๊ฐ์ง ์ ๋ฐ์ ์๋ ์ํฉ์ด ์๊น
(ํด์ ์ถฉ๋)
=> HashSet, HashMap๊ณผ ๊ฐ์ ํด์ ๊ธฐ๋ฐ ์ปฌ๋ ์ ๋ค์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๊ฒ์ํ ๋ hashCode()๋ฅผ ๋จผ์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ๋์ด๊ธฐ ๋๋ฌธ์ ์ด ๊ท์ฝ์ ์ด๊ธฐ๋ฉด, ์ปฌ๋ ์ ์ด ๊ฐ์ฒด๋ฅผ ์ ๋๋ก ์ฐพ์ง ๋ชปํ๋ ๋ฑ์ ์ฌ๊ฐํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ผญ equals()๋ฅผ ์ฌ์ ์ํ ๋๋ hashCode()๋ ํจ๊ป ์ฌ์ ์ ํด์ค์ผํจ
=> ํด์ ๊ธฐ๋ฐ ์ปฌ๋ ์ ์ ๋ด๋ถ ๋์์ ์ดํด๋ณด๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฃ์ ๋ hashCode()๋ก ํด์๊ฐ ๊ณ์ฐ ํ ์ด๋ฅผ ์ด์ฉํด ๋ฒํท ์์น๋ฅผ ์ฐพ์, ๋ง์ฝ ํด๋น ๋ฒํท์ ๊ฐ์ ํด์๊ฐ์ ๊ฐ์ฒด๊ฐ ์ด๋ฏธ ์์ผ๋ฉด equals()๋ก ์ต์ข ๋น๊ตํ์ฌ ๊ฐ์ ๊ฐ์ฒด์ธ์ง ํ๋จํ๊ณ ๊ฐ์ผ๋ฉด ๋ฎ์ด์ฐ๊ธฐ, ๋ค๋ฅด๋ฉด ์ฒด์ด๋(๋ฆฌ์คํธ์ ์ถ๊ฐ)
=> ๊ทธ๋์ ํด์ ์ถฉ๋์ด ๋ฐ์ํ๋ฉด ํ ๋ฒํท ์์ ์ ์ฅ๋๋ ๊ฐ์ฒด ์๊ฐ ๋ง์์ง๋ฏ๋ก equals()๋ก ์ผ์ผ์ด ๋น๊ตํด์ผ ํ๋ O(1)์ ๊ฐ๊น๋ ์ฑ๋ฅ์ด O(n)์ ๊ฐ๊น์์ง
(๋ฐ์ดํฐ ์์ด ์ปค์ง์๋ก ์ฑ๋ฅ ์ ํ ์ฒด๊ฐ์ด ํผ)
String์ ๊ฐ์ฒด์ธ๋ฐ == ๋น๊ตํด๋ ๋๋๋ฐ?
String์ ๊ฐ์ฒด์ธ๋ฐ ==๋ก ๋น๊ตํด๋ ์ ๋๋ ๊ฒฝ์ฐ๊ฐ ์์
=> ์ด๋ ๋ฌธ์์ด ์์ ํ(String Constant Pool)์ด๋ผ๋ ํน๋ณํ ๋ฉ๋ชจ๋ฆฌ ์์ญ ๋๋ฌธ์
public class StringComparison {
public static void main(String[] args) {
// "์๋
ํ์ธ์" ๋ฆฌํฐ๋ด์ String Constant Pool์ ์ ์ฅ๋๊ณ , str1๊ณผ str2๋ ๊ฐ์ ์ฃผ์๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
String str1 = "์๋
ํ์ธ์";
String str2 = "์๋
ํ์ธ์";
// new ํค์๋๋ Heap ๋ฉ๋ชจ๋ฆฌ์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๊ฐ์ ๋ก ์์ฑํฉ๋๋ค.
String str3 = new String("์๋
ํ์ธ์");
// ๋์ผ์ฑ ๋น๊ต (๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๋น๊ต)
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // false
// ๋๋ฑ์ฑ ๋น๊ต (๋ด์ฉ ๋น๊ต) - String ํด๋์ค์๋ equals()๊ฐ ์ด๋ฏธ ์ ์ฌ์ ์๋์ด ์์ต๋๋ค.
System.out.println(str1.equals(str3)); // true
}
}
์ฝ๋ ๋ฆฌํฐ๋ด("...")๋ก ์์ฑํ ๋ฌธ์์ด์ ์ปดํ์ผ ์์ ์ ๋ฌธ์์ด ์์ ํ(String Constant Pool)์ ์ ์ฅ๋์ด ์ฌ์ฌ์ฉ๋จ
=> ์ ์ฝ๋์์ str1๊ณผ str2๋ ๊ฐ์ ์ฃผ์(๋์ผํ ๋ฌธ์์ด ๋ฆฌํฐ๋ด)๋ฅผ ์ฐธ์กฐํ์ฌ == ๋น๊ต๊ฐ true๊ฐ ๋์ด
ํ์ง๋ง new String()์ ๋ฌด์กฐ๊ฑด Heap ์์ญ์ ์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ฃผ์๊ฐ ๋ฌ๋ผ false๊ฐ ๋จ
์ด๋ฌํ ๋์ ๋ฐฉ์์ ์ฐจ์ด ๋๋ฌธ์ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ๊ธฐ ์ฌ์ฐ๋ฏ๋ก ๋ฌธ์์ด์ ๋ด์ฉ์ ๋น๊ตํ ๋๋ ํผ๋์ ํผํ๊ธฐ ์ํด ํญ์ equals() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์์ ํจ
Integer ๊ฐ์ ๋ํผ ํด๋์ค๋ ์ด๋ป๊ฒ ๋น๊ต?
Integer, Long๊ณผ ๊ฐ์ ๋ํผ ํด๋์ค๋ ๊ฐ์ฒด์ด๋ฏ๋ก ์์น์ ์ผ๋ก equals()๋ฅผ ์ฌ์ฉํด ๊ฐ์ ๋น๊ตํด์ผํจ
=> ํ์ง๋ง, Integer์ ๊ฒฝ์ฐ์๋ String ์ฒ๋ผ ์บ์ฑ(caching) ๊ธฐ๋ฅ์ด ์กด์ฌ
(๊ธฐ๋ณธ์ ์ผ๋ก -128 ~ 127 ๊น์ง์ Integer ๊ฐ์ ๋ด๋ถ ์บ์์ ์ ์ฅ๋์ด ๊ณต์ ๋จ)
Integer i1 = 100; // Integer.valueOf(100)์ผ๋ก ๋ณํ (์คํ ๋ฐ์ฑ)
Integer i2 = 100;
System.out.println(i1 == i2); // true (์บ์๋ ๋ฒ์ ๋ด์ ๊ฐ์ด๋ฏ๋ก ๊ฐ์ ๊ฐ์ฒด ์ฐธ์กฐ)
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i3 == i4); // false (์บ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์๋ก์ด ๊ฐ์ฒด ์์ฑ)
System.out.println(i3.equals(i4)); // true (๊ฐ ์์ฒด๋ ๊ฐ์ผ๋ฏ๋ก equals()๋ true)
์ ์ฝ๋์ฒ๋ผ ํน์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด == ๋น๊ต ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ฏ๋ก, ๋ํผ ํด๋์ค์ ๊ฐ์ ๋น๊ตํ ๋๋ ์ผ๊ด์ฑ ์๊ณ ์์ ํ equals() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผํจ
์ ๋ฆฌ
| ๊ตฌ๋ถ | == ์ฐ์ฐ์ | equals() ๋ฉ์๋ |
| ๋น๊ต ๋์ | ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ ๊ฐ | ๊ฐ์ฒด์ ๋ ผ๋ฆฌ์ ๋ด์ฉ |
| ๊ฐ๋ | ๋์ผ์ฑ | ๋๋ฑ์ฑ |
| ์ฌ์ฉ | ์์ ํ์ (primitive type) ๋น๊ต | ๊ฐ์ฒด(Object)์ ๋ด์ฉ ๋น๊ต |
| ์ฃผ์์ฌํญ | String, Wrapper ํด๋์ค์ ์ฌ์ฉ ๊ธ์ง | ์ฌ์ฉ์ ์ ์ ํด๋์ค๋ hashCode() ์ ํจ๊ป ๋ฐ๋์ ์ฌ์ ์ |
'๐ป CS > ๋งค์ผ๋ฉ์ผ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ๋๊ธฐ, ๋น๋๊ธฐ / ๋ธ๋กํน, ๋ ผ๋ธ๋กํน (@Async) (3) | 2025.08.16 |
|---|---|
| TCP 3-way handshake & 4-way handshake (6) | 2025.08.14 |
| ํฐ์บฃ(Tomcat)์ด๋? (5) | 2025.08.05 |
| ์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ์ ์ฐจ์ด (4) | 2025.08.04 |
| RAID(Reduntant Array of Independent Disks) ๊ธฐ์ ์ด๋? (0) | 2025.07.07 |