우선, 글을 작성하기 전 이 글의 모든 내용은 김영한님의 JAVA 강의를 바탕으로 함을 알립니다.
List : 순서 유지, 중복 허용, 인덱스 접근 가능의 특징을 갖는 선형 자료구조 (앞에서 많이 언급)Set : 유일한 요소의 컬렉션Set의 요소는 중복이 불가능 Set의 요소는 순서가 정해져 있지 않음
public class MyHashSetV0 {
private int[] elementData = new int[10];
private int size = 0;
// O(n)
public boolean add(int value) {
if (contains(value)) {
return false;
}
elementData[size] = value;
size++;
return true;
}
// O(n)
public boolean contains(int value) {
for (int data : elementData) {
if (data == value) {
return true;
}
}
return false;
}
public int size() {
return size;
}
@Override
public String toString() {
return "MyHashSetV0{" +
"elementData=" + Arrays.toString(Arrays.copyOf(elementData,size)) +
", size=" + size +
'}';
}
}
Set을 구현한 결과 Set의 특성상 중복이 허용되면 안되기 때문에 add() 메서드에서 중복되지 않은 대상만 요소로 추가가 가능하도록 contains()를 통해 배열의 모든 요소를 검사하는 과정을 진행한다.배열을 데이터의 저장소로 사용한 Set의 경우를 다시 생각해보자. 배열의 경우 인덱스를 통한 조회하는 기능은 O(1)으로 높은 성능을 갖는다. 그렇다면 데이터를 배열의 인덱스로 사용한다면 인덱스 조회와 데이터 검색이 함께 가능하지 않을까??
즉, 입력되는 데이터를 동일한 인덱스 공간에 저장하면 조회와 검색이 빨라지지 않을까?

하지만 낭비되는 메모리가 너무 많다. 만약에 int의 모든 범위에서 특정 숫자를 Set 자료구조에 추가한다고 가정하면 빈공간으로만 메모리를 거의 다 사용하는 상황이 발생한다. 메모리를 절약하면서, 넓은 범위의 값을 사용할 수 없을까? 나머지 연산을 사용하면 가능하다. 예를들어, 배열의 크기를 10으로 고정했다고 가정하자.
1 % 10 = 12 % 10 = 23 % 10 = 34 % 10 = 45 % 10 = 524 % 10 = 499 % 10 = 9해시 인덱스(hashIndex) 란 배열의 인덱스로 사용할 수 있도록 원래의 값을 계산한 인덱스를 의미한다.

99와 9를 모두 10으로 나누면 동일한 나머지인 9를 해시 인덱스로 갖게 된다. 이렇게 해시 충돌이란 다른 값을 입력했지만 같은 해시 코드가 나오는 것을 의미한다. 어떻게 해야할까?

해시충돌이 발생한 경우 내부의 데이터를 하나씩 비교해보면 결과를 찾을 수 있다. 위의 예에서 99를 조회한다고 가정하자.

equals()를 통해 배열내의 모든 값을 비교하여 99를 검색 해시 충돌 상황에서의 값 조회 과정을 살펴보니 추가되는 데이터에의해 특정 인덱스에 데이터가 많이 몰리는 경우가 발생할 수 있다.

해시 인덱스는 9가 된다O(n)의 성능을 갖게 된다. 해시 알고리즘에 의한 해시 인덱스를 사용하는 경우