Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- stream groupingby
- javascript image slider
- github action codedeploy
- 코드포스
- github ec2 deploy
- lombok Builder
- github CI
- java hashCode
- AWS Codedeploy
- github action
- github deploy
- list remove
- SpringBootApplication
- vanilla js image slider
- hashcode override
- equals
- java 비동기처리
- c++ 빌드
- equals override
- AliasFor
- Java Wrapper Class
- Spring Aspect
- kotest
- Java
- github CI/CD
- Java lombok
- Github action deploy
- java stream api
- image slider
- java CompletableFuture
Archives
- Today
- Total
기록창고
hashCode() override 본문
Map이나 Set에서 key 값을 저장할 때 해쉬를 해서 저장을 한다.
hash를 하기 위해서, Object class 안에 있는 hashCode() 라는 함수를 사용합니다.
public native int hashCode();
함수는 이렇게 생겼고 뭔지 모르겠지만, int 값을 반환하는 것을 알 수 있습니다.
그래서 Object 마다 모두 hashCode()를 사용할 수 있고, 실제로 hashCode를 통해 해쉬하는 것을 볼 수 있습니다.
아래 코드는 HashMap에 구현되어있는 코드입니다.
put 을 할때 key를 hash하여 넣는 것을 볼 수 있습니다
public V put(K key, V value) {
return this.putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return key == null ? 0 : (h = key.hashCode()) ^ h >>> 16;
}
아래 예제는 String 를 Set안에 넣어서 사이즈를 확인하는 코드입니다.
Set은 중복이 안되기 때문에 size가 1로 출력되는 것을 알 수 있습니다
public class Main {
public static void main(String[] args) {
Set<String> stringSet = new HashSet<>();
String a = "hello";
String b = "hello";
stringSet.add(a);
stringSet.add(a);
System.out.println(stringSet.size()); // 1
System.out.println(a.hashCode()); //99162322
System.out.println(b.hashCode()); //99162322 hash가 값이 같아서, 중복되지않고 Set에 추가되지 않았다.
}
}
하지만 String Class 말고 사용자 정의 클래스를 보면 다르다.
class MyClass {
public String myClassString;
public MyClass(String myClassString) {
this.myClassString = myClassString;
}
}
public class Main {
public static void main(String[] args) {
Set<MyClass> set= new HashSet<>();
MyClass myClass1 = new MyClass("first item");
MyClass myClass2 = new MyClass("first item");
set.add(myClass1);
set.add(myClass2);
System.out.println(set.size()); // 2
System.out.println(myClass1.hashCode()); //381259350
System.out.println(myClass2.hashCode()); //2129789493
}
}
위의 출력에서도 myClass1, 2에서 해쉬한 값이 다르기 때문에 Set 안에 중복되게 들어간 것을 볼 수 있다.
이런 문제를 없애기 위해 hashCode()를 오버라이드해서 다시 정의를 해야한다!
String Class는 이미 override를 해주었기 때문에 위와 같은 문제가 발생하지 않았다..
그래서 MyClass를 아래와 같이 다시 작성하면 원하는 방향으로 동작할 거 같다.
class MyClass {
public String myClassString;
public MyClass(String myClassString) {
this.myClassString = myClassString;
}
@Override
public int hashCode() {
// 지금은 String field 만을 가지고 있기 때문에 String의 hashCode를 사용한다.
// 실제로 이렇게 구현하면 안된다!
return this.myClassString.hashCode();
}
}
MyClass에서 hashCode 만 오버라이드해서 위의 코드를 실행시키면 잘 될거 같은데, 안된다...
System.out.println(set.size()); //2
System.out.println(myClass1.hashCode()); // -219298173
System.out.println(myClass2.hashCode()); // -219298173 같은 해쉬값이 출력됬음에도 불구하고 사이즈는 그대로 2이다..
....
다음 에 계속
'JAVA' 카테고리의 다른 글
String.equals() (0) | 2020.01.19 |
---|---|
Collectors GroupingBy (0) | 2020.01.16 |
JAVA List for 문으로 remove하기 (0) | 2020.01.05 |
equals() override (0) | 2019.12.28 |
static 에 관하여 (0) | 2019.12.22 |
Comments