Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String이 hashCode()를 오버라이딩한 이유 #2

Open
beginin15 opened this issue Aug 8, 2021 · 4 comments
Open

String이 hashCode()를 오버라이딩한 이유 #2

beginin15 opened this issue Aug 8, 2021 · 4 comments
Labels
Java Java 관련 주제

Comments

@beginin15
Copy link
Member

beginin15 commented Aug 8, 2021

image

  1. A1.hashCode()와 A2.hashCode()의 값은 같을까 다를까?
  2. A1 == A2의 결과는 true일까 false일까?
  3. A1.equals(A2)의 결과는 true일까 false일까?

Q. 여기서 1번의 결과는 같다. 이유는 String이 hashCode()를 재정의 했기 때문. 왜 재정의 되어있는가?

@beginin15 beginin15 added the Java Java 관련 주제 label Aug 8, 2021
@beginin15 beginin15 changed the title String이 hashcode 메소드를 오버라이딩한 이유 String이 hashCode()를 오버라이딩한 이유 Aug 8, 2021
@suhyunsim
Copy link
Member

개발하면서 String을 HashXXX의 Key로 사용하는 경우가 많다.
만약 hashCode가 오버라이딩 되어있지 않다면? 다음과 같은 상황이 발생한다.

  1. 같은 문자열도 다른 key로 인식되어 저장됨, get으로 값을 얻어올 때 같은 문자열이더라도 key가 다름
  2. 모든 프로젝트에서 String을 상속하는 새로운 클래스를 만들고 hasCode를 오버라이딩해서 사용해야 함
  • 참고: 논리적 동등 비교시 hashCode()를 오버라이딩 해야한는데 Collection 프레임워크에 HashSet, HashMap, HashTable은 아래와 같은 방법으로 동등비교를 한다.
  1. 먼저 hashCode() 값을 비교
  2. equals()로 동등 비교
  3. 위에 과정이 true면 동등한 객체이다.

@suhyunsim
Copy link
Member

참고할 주제: 동등성과 동일성

@beginin15
Copy link
Member Author

질문의 의도는 객체의 동등성 비교를 설명하기 위한 것이고 ‘String’을 예시로 들으신건가 보네요!

우리가 클래스를 작성할 때 항상 ‘equals()’랑 ‘hashCode()’를 함께 재정의하는 이유랑 동일한 맥락인 것 같아요.

저는 ‘String’만의 특성이 따로 있는건가 싶어서 이것저것 찾아봤는데 질문의 의도에서 벗어난 것 같긴 하지만 겸사겸사 JVM의 상수풀에 대해서도 공부해보면 좋을 것 같다는 생각이 들었어요.ㅎㅎ

@suhyunsim
Copy link
Member

제이의 얘기를 참고해서 지난 번에 정리한 constant pool 내용도 살짝 가져왔어요!

Constant Pool

String 객체를 생성하는 방법

Literal ("")

  • 내용이 같다면 같은 객체
@DisplayName("literal로 생성 시 동일")
@Test
void stringLiteral() {
    String str1 = "abcde";
    String str2 = "abcde";
    assertThat(str1).isEqualTo(str2);
}

new 연산자 사용

  • 내용이 같아도 개별적인 객체
@DisplayName("new로 생성한 String 객체는 값이 같아도 동일하지 않음")
@Test
void stringNew() {
    String str1 = new String("1234");
    String str2 = new String("1234");
    assertThat(str1).isNotSameAs(str2);
}
  • intern() 메서드로 String Pool에 있으면 그 객체를 그대로 리턴, 그렇지 않으면 String Pool에 추가하고 객체의 reference를 리턴
@DisplayName("String Pool 바깥에 있던 String 객체를 intern -> String Pool에 추가")
@Test
void internedString() {
    String constant = "interned String";
    String newString = new String("interned String");
    assertThat(constant).isNotSameAs(newString);

    String internedString = newString.intern();
    assertThat(constant).isSameAs(internedString);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java Java 관련 주제
Projects
None yet
Development

No branches or pull requests

2 participants