public class Object {
public boolean equals(Object obj) {
return (this == obj);
}
// 두 객체의 같고 다름을 참조변수의 주소값으로 판단
public native int hashCode();
// 해시함수는 찾고자하는 값을 입력하면, 그 값이 저장된 위치를 알려주는 해시코드를 반환
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 클래스이름에 16진수의 해시코드
}
public class Arrays {
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
}
String.equals는 가지고 있는 값이 동일하면 TRUE
String == 연산자는 주소값을 비교하지만, Object 클래스에서의 equals는 equality is the same as object identity, 즉. 객체 동일성이다.
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TestObject that = (TestObject) o;
return id == that.id && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + (int) id;
hash = 31 * hash + (name == null ? 0 : name.hashCode());
hash = 31 * hash + (email == null ? 0 : email.hashCode());
return hash;
}
@Override
public String toString() {
return "TestObject{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index {@code i} such that
* {@code Objects.equals(o, get(i))},
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
return indexOfRange(o, 0, size);
}
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractList() {
}
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
}
경우 | equals()와 hashCode() 필요 여부 | 비고 |
---|---|---|
HashSet, HashMap, HashTable 사용 | ✅ 필요 | |
contains(), containsKey() 사용 | ✅ 필요 | |
TreeSet, TreeMap 사용 | ✅ 필요 (Comparable과 함께) | |
객체의 참조 값 비교 (각 객체가 고유해야 함) | ❌ 불필요 | |
Enum 타입 | ❌ 불필요 |
https://www.baeldung.com/java-hashcode#standard-hashcode-implementations
https://velog.io/@jyleedev/EqualsAndHashCode-%EA%B7%B8%EB%A6%AC%EA%B3%A0-HashCode%EC%99%80-Equals
https://velog.io/@user1/EqualsAndHashCode-%EC%9D%98-%EC%98%B5%EC%85%98
https://velog.io/@injoon2019/%EC%9E%90%EB%B0%94-equals-hashCode-toString
contains()