Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

AI가 번역한 다른 언어 보기

제이온

equals() vs hashCode()

  • 작성 언어: 한국어
  • 기준국가: 모든 국가 country-flag

언어 선택

  • 한국어
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

durumis AI가 요약한 글

  • equals()는 객체의 내용이 같은지 비교하는 메서드이고, hashCode()는 객체의 고유한 정수 값을 반환하는 메서드입니다.
  • 두 메서드는 함께 사용하여 해시 기반 자료 구조에서 객체의 동등성을 효율적으로 검사하는 데 사용됩니다.
  • equals()를 재정의할 때 hashCode()도 함께 재정의하여 동일한 객체에 대해 동일한 해시 코드를 반환하도록 하는 것이 좋습니다.

equals()

equals() 는 객체의 내용이 같은지 비교한다. 흔히 동등 비교라고 하며, equals() 를 재정의하지 않을 경우 내부적으로 ==와 같으므로 동일 비교가 된다. 따라서 올바르게 객체를 동등 비교하고 싶다면 반드시 equals() 를 사용해야 한다.


public boolean equals(Object obj) { 
    return (this == obj); 
}


hashCode()

hashCode() 는 두 객체가 같은 객체인지 확인한다. == 과 같은 동일 비교 기능을 하지만, hashCode() 메소드는 반환 값으로 런타임 중 객체의 유일한 정수 값을 반환한다. 일반적으로 Heap에 저장된 객체의 메모리 주소를 반환한다.


public native int hashCode();


해당 메소드는 native 키워드가 붙여져 있는데, 이것은 Java 외의 언어에서 개발된 언어를 Java에서 사용할 경우 사용하는 키워드이다.


해시란?

해싱은 해시 함수를 사용하여 가변 크기의 입력 값에서 고정된 크기의 출력 값을 생성하는 과정을 의미한다. 해싱을 통해 얻어 온 값을 해시 코드라고 한다.


equals()와 hashCode()

동일한 객체는 동일한 메모리 주소를 가져야 하므로, 동일한 객체는 동일한 해시 코드를 가져야 한다는 것은 자명하다. 따라서 equals() 말고 hashCode() 도 같이 재정의하여 동일한 해시 코드를 보장하도록 코드를 짜는 것이 바람직하다.


해시 자료 구조

public class Main {

    public static void main(String[] args) throws IOException {
        Set people = new HashSet<>();

        people.add(new Person("제이온", 23));
        people.add(new Person("제이온", 23));
        System.out.println(people.size()); // 2
    }
}

class Person {

    private final String name;

    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }
}


위와 같이 HashSet 자료 구조에 동등한 객체 2개를 삽입해 보자. 해당 Set의 사이즈를 출력하면 2가 나올 것이다. 왜 그럴까?


바로 해시를 사용한 자료 구조는 Key를 결정할 때 hashCode() 를 사용하기 때문이다. 즉, 객체가 동일한지 비교하기 전에, 두 객체의 해시 코드가 같은지 비교하고 그 후 두 객체가 동등한지 판단한다. 이때, hashCode() 가 재정의되어 있지 않다면 Object의 hashCode()를 사용하므로 각 객체가 저장된 메모리 주소가 반환된다. 따라서 해시 자료 구조를 사용하는 경우를 위해 equals() 외에 hashCode() 도 재정의해 주는 것이 좋다.


public static void main(String[] args) throws IOException {
        Set people = new HashSet<>();

        people.add(new Person("제이온", 23));
        people.add(new Person("제이온", 23));
        System.out.println(people.size()); // 1
    }
}

class Person {

    private final String name;

    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}


출처


예상 면접 질문 및 답변

equals()와 hashCode()는 왜 같이 사용하는가?

해시를 사용한 자료 구조는 Key를 결정할 때 hashCode() 를 사용하기 때문이다. 즉, 객체가 동일한지 비교하기 전에, 두 객체의 해시 코드가 같은지 비교하고 그 후 두 객체가 동등한지 판단한다. 이때, hashCode() 가 재정의되어 있지 않다면 Object의 hashCode()를 사용하므로 각 객체가 저장된 메모리 주소가 반환된다. 따라서 해시 자료 구조를 사용하는 경우를 위해 equals() 외에 hashCode() 도 재정의해 주는 것이 좋다.

제이온
제이온
제이온
제이온
[이펙티브 자바] 아이템 6. 불필요한 객체 생성을 피하라 자바에서 불필요한 객체 생성을 최소화하여 성능을 향상시키는 방법에 대해 설명합니다. 문자열, 부울, 정규 표현식, 뷰 객체, 오토 박싱 등 다양한 예시와 함께 객체 재사용의 중요성을 강조합니다. 특히 방어적 복사가 필요한 경우 객체 재사용으로 인한 문제점을 주의해야 합니다.

2024년 4월 28일

[Java] Synchronized Collection vs Concurrent Collection 자바에서 동기화된 컬렉션(Vector, Hashtable, Collections.synchronizedXXX)은 멀티 스레드 환경에서 동시성을 보장하지만, 성능 저하와 여러 연산을 묶어 사용할 때 문제 발생 가능성이 있습니다. 대안으로 java.util.concurrent 패키지의 병렬 컬렉션(CopyOnWriteArrayList, ConcurrentHashMap 등)을 사용하면 읽기 성능 향상과 효율적인 동시성 처리가 가능합니다.

2024년 4월 25일

[이펙티브 자바] 아이템 1. 생성자 대신 정적 팩터리 메서드를 고려하라 정적 팩터리 메서드는 생성자 대신 인스턴스를 생성하는 데 사용할 수 있는 유용한 방법입니다. 이름을 가질 수 있고, 생성자보다 더 많은 유연성을 제공하며, 플라이웨이트 패턴, 싱글톤 패턴, 서비스 제공자 프레임워크와 같은 디자인 패턴을 구현하는 데 사용할 수 있습니다.

2024년 4월 27일

[Javascript] Object의 구조 (V8) JavaScript에서 Object는 내부적으로 해시테이블과 유사한 방식으로 동작하지만, V8 엔진에서는 Hidden class를 이용하여 Fast 모드와 Dictionary 모드로 변환되어 성능을 최적화합니다. Hidden class는 객체의 구조를 정의하고 Fast 모드에서는 빠른 속도를 제공하지만, 키 추가 등의 변화가 발생하면 Dictionary 모드로 전환되어 해시테이블처럼 동작하며 성능이 저하될 수 있습니다.
곽경직
곽경직
곽경직
곽경직
곽경직

2024년 3월 18일

[비전공, 개발자로 살아남기] 14. 신입 개발자 자주 묻는 기술면접 내용 요약 신입 개발자 면접에서 자주 나오는 기술 질문과 답변을 정리했습니다. 메모리 영역, 자료구조, 데이터베이스, 프로그래밍 패러다임, 페이지 교체 알고리즘, 프로세스와 스레드, OSI 7 계층, TCP와 UDP 등 다양한 주제를 다룹니다.
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

2024년 4월 3일

개념적 데이터 모델링 개념적 데이터 모델링은 정보를 엔티티로 분리하고, 엔티티 간의 관계를 ERD로 표현하는 과정입니다. 엔티티는 독립적인 데이터 저장 단위이며, 속성은 엔티티가 가진 데이터를 의미합니다. ERD에서는 식별자를 사용하여 엔티티를 고유하게 식별하며, 식별자는 기본 키, 후보 키, 대체 키, 중복 키 등으로 구분됩니다. 엔티티 간의 관계는 존재에 의한 관계와 행위에 의한 관계로 나뉘며, 카디널리티와 옵셔널리티를 통해 수적 관계와 필수/선택적 관계를 표현합니다.
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024년 4월 8일

물리적 데이터 모델링 물리적 데이터 모델링은 논리적 데이터 모델링을 기반으로 저장 공간 효율성, 오브젝트 파티셔닝, 인덱스 최적화 등 성능 향상에 중점을 둡니다.
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

2024년 4월 9일

JWT(JSON Web Token)이란? JSON Web Token(JWT)은 정보를 안전하게 전송하는 방법으로, 헤더, 페이로드, 서명으로 구성됩니다. 서버는 개인 키를 사용하여 서명을 생성하고, 토큰의 무결성과 보안을 유지합니다. JWT는 self-contained하고 stateless하여 세션의 단점을 보완하고 분산 시스템 및 마이크로서비스 아키텍처에서 확장성을 높입니다.
Seize the day
Seize the day
Seize the day
Seize the day
Seize the day

2024년 3월 4일

[Concurrency] Atomic Operation: Memory Fence와 Memory Ordering Atomic 연산에서 메모리 순서를 고려하는 것은 동시성 처리에 필수적입니다. CPU 최적화로 인해 명령어 순서가 바뀌는 현상이 발생할 수 있으며, 이는 동시성 환경에서 문제를 일으킬 수 있습니다. Memory Fence와 Ordering 옵션을 통해 이러한 문제를 해결할 수 있습니다. Ordering 옵션에는 Relaxed, Acquire, Release, AcqRel, SecCst가 있으며, 각각 다른 수준의 메모리 순서 보장을 제공합니다.
곽경직
곽경직
곽경직
곽경직
곽경직

2024년 4월 12일