코자개는 코딩 테스트로부터 자바 개념을 줄인 나만의 용어다.
이전에 배웠던 자바 개념들을 코테를 풀면서 상기시키고 있다..
원래는 개념 -> 코테지만.. 나의 학습 방법은 코테를 통해 개념을 학습시키는 것이다.
완전 노베이스는 아니기 때문에 문제를 풀면서 잊어버린 개념이나 몰랐던 것들을 채우는 시간이 될 수 있을 것이다.
<문자열>에 관한 문제를 풀면서 정확하게 기억하고 가야할 개념들이 많았다. 그중에서도 == 와 equals()의 사용이었는데,
한 번 다뤄보도록 하겠다.
== vs equals()
1) ==
처음에 문자열을 비교할 때 아무생각 없이 ==를 사용했다.
기본형에서의 == 는 값 자체를 비교하는 것이지만, 참조 비교를 할 때에는 메모리 주소를 비교한다.
int a = 10;
int b = 10;
System.out.println(a == b); // true (값이 동일)
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // false (다른 객체)
2) equals()
객체의 내용이 같은지 비교할 때 사용한다.
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // true (내용이 같음)
String 클래스는 equals() 메서드를 오버라이딩해서 문자열의 내용을 비교하도록 구현한다.
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 같은 객체면 true
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return this.name.equals(person.name); // 이름이 같으면 true
}
}
Person p1 = new Person("John");
Person p2 = new Person("John");
System.out.println(p1 == p2); // false (서로 다른 객체)
System.out.println(p1.equals(p2)); // true (내용이 같음)
위의 코드를 보면 p1 == p2는 당연히 false이다. -> 주소값을 비교했을 때 서로 다르기 때문이다.
하지만 p1.equals(p2)는 equals()를 오버라이딩 했기 때문에 내용이 같으므로 true이다.
3) String 에서 == 와 equals()
String str1 = "hello"; // String Pool 사용
String str2 = "hello"; // 같은 "hello"를 가리킴
String str3 = new String("hello"); // new로 생성 (Heap 메모리)
String str4 = new String("hello");
System.out.println(str1 == str2); // true (String Pool에서 같은 객체를 공유)
System.out.println(str1.equals(str2)); // true (내용이 같음)
System.out.println(str1 == str3); // false (다른 메모리 영역)
System.out.println(str1.equals(str3)); // true (내용이 같음)
System.out.println(str3 == str4); // false (new로 생성된 다른 객체)
System.out.println(str3.equals(str4)); // true (내용이 같음)
4) hashCode()
- equals()를 오버라이딩하면 주의해야할 점이 있는데, 반드시 hashCode()도 오버라이딩 해야한다.
왜인지 코드를 보면서 이해해보자
class Person {
String name;
Person(String name) { this.name = name; }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return this.name.equals(((Person) obj).name);
}
}
Person p1 = new Person("John");
Person p2 = new Person("John");
HashSet<Person> set = new HashSet<>();
set.add(p1);
set.add(p2);
System.out.println(set.size()); // 2 (중복 저장됨)
hashCode()를 오버라이딩하지 않으면 HashSet이 p1과 p2를 다른 객체로 인식해서 중복 저장된다.
그래서
class Person {
String name;
Person(String name) { this.name = name; }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return this.name.equals(((Person) obj).name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
HashSet<Person> set = new HashSet<>();
set.add(new Person("John"));
set.add(new Person("John"));
System.out.println(set.size()); // 1 (중복 제거됨)
이와 같이 hashCode()를 오버라이딩해서 p1과 p2를 같은 객체로 인식하게 해야한다.
즉, == 은 (기본형일 때를 제외하고) 주소값을 비교할 때 사용하며 equals()는 내용을 비교할 때 사용한다.
'자바' 카테고리의 다른 글
| 코자개 - Hash (1) | 2025.04.11 |
|---|---|
| 자바 정처기 실기 대비 (1) | 2025.04.07 |
| java 복습 3 (0) | 2024.01.14 |
| java 복습 2 (0) | 2024.01.14 |
| java 복습 1 (0) | 2024.01.04 |