CodeGym /Java Blog /무작위의 /자바 해시 테이블
John Squirrels
레벨 41
San Francisco

자바 해시 테이블

무작위의 그룹에 게시되었습니다
Java Hashtable 클래스는 Java Collection Framework의 가장 오래된 멤버 중 하나입니다. 수학적 해시 테이블 데이터 구조의 구현입니다. Java 해시 테이블에는 내부적으로 키/값 쌍이 저장되는 버킷이 포함되어 있습니다. Hashtable은 HashMap 과 매우 유사합니다 . 그들 사이의 가장 중요한 차이점은 Hashtable이 동기화되는 반면 HashMap은 동기화되지 않는다는 것입니다.

데이터 구조로서의 해시 테이블

Hashtable은 데이터가 배열 형식으로 저장되는 데이터 구조입니다. 모든 데이터 값에는 고유한 키 값이 있습니다. 키가 알려진 경우 필요한 데이터에 대한 액세스가 매우 빠릅니다. 따라서 삽입 및 검색 작업은 데이터 크기에 관계없이 빠릅니다. Hash Table은 데이터를 보관하기 위한 배열과 요소가 위치해야 할 인덱스 생성을 위한 해싱으로 구성됩니다. 해싱이란 무엇입니까? 객체를 일련의 문자(코드)로 매핑하는 규칙입니다. 일반적으로 이러한 종류의 함수는 큰 데이터 조각을 작은 정수 값으로 변환합니다. 해시 함수는 다를 수 있지만 모두 특정 속성을 제출합니다.
  • 특정 개체에는 특정 해시 코드가 있습니다.
  • 두 개의 동일한 개체에는 동일한 해시 코드가 있습니다. 그 반대는 사실이 아닙니다.
  • 두 개의 해시 코드가 다르면 개체가 확실히 같지 않습니다.
  • 다른 개체는 동일한 해시 코드를 가질 수 있습니다. 이 매우 드문 이벤트는 충돌을 호출합니다. 좋은 해시 함수는 충돌 가능성을 최소화합니다.
Object에 Hash Function을 적용한 결과 hashCode를 호출합니다 .

Java의 해시 테이블

Hashtable 클래스는 해시 테이블 데이터 구조의 구현입니다. 이 컬렉션은 Java Collection Framework보다 먼저 생성되었지만 나중에 포함되었습니다. 모든 "초기" 컬렉션(Java 1.0부터)과 마찬가지로 해시 테이블은 동기화됩니다(거의 모든 메서드가 동기화됨으로 표시됨). 이 요소 때문에 해시 테이블에는 심각한 성능 문제가 있습니다. 따라서 Java 1.2부터 대부분의 경우 동기화 부족으로 인해 Map 인터페이스 의 다른 구현을 사용하는 것이 좋습니다 . 일반적으로 HashMap이 가장 적절한 대체품입니다. 그래서 클래스 Hashtable<K,V>키와 값으로 구성됩니다. 해싱 원칙에 따라 키를 저장합니다. 키-값 쌍은 "버킷"에 저장됩니다. 버킷은 일종의 내부 배열인 "테이블"을 구성합니다. Hashtable은 키의 해시 코드를 사용하여 키/값 쌍이 매핑되어야 하는 버킷을 결정합니다. 해시 함수를 사용하면 키의 해시코드에서 버킷 위치를 가져올 수 있습니다. 이 함수는 개체에 대한 정수를 반환합니다. 위에서 말했듯이 두 개의 동일한 개체는 동일한 해시 코드를 갖는 반면 두 개의 다른 개체는 항상 다른 해시 코드를 갖지 않을 수 있습니다. 해시 테이블에 넣은 다른 개체는 동일한 해시 코드를 가질 수 있습니다. 이 문제(충돌)를 해결하기 위해 목록 배열이 해시 테이블에 사용됩니다. 단일 버킷에 매핑된 쌍은 목록에 저장되고 이 목록 참조는 배열 인덱스에 저장됩니다.

해시 테이블 Java 생성자

  • Hashtable() , 기본 생성자. 빈 해시 테이블을 생성합니다. (기본 초기 용량 = 11, 부하율 = 0.75).
  • Hashtable(int size)은 지정된 크기의 해시 테이블을 구성합니다.
  • Hashtable(int size, float fillRatio)은 지정된 크기와 채우기 비율의 해시 테이블을 생성합니다.
  • Hashtable(Map m)은 주어진 Map과 동일한 매핑으로 해시 테이블을 생성합니다.

해시 테이블 선언

Hashtable Java 클래스는 Map , Cloneable Serializable 인터페이스 를 구현합니다 . 그것은 Dictionary 클래스를 확장합니다.

Hashtable.java
public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable
K 는 맵에서 유지 관리하는 키 유형입니다. V 는 매핑된 값의 유형입니다. 예:

Hashtable<Student, Integer> myHTable = new Hashtable<>();

해시 테이블 자바를 가져오는 방법

Java Hashtable은 java.util 패키지 안에 있습니다 . 따라서 import java.util.Hashtable을 사용하십시오. 귀하의 코드에서. 일반적으로 이에 대한 힌트는 IDE에서 얻을 수 있습니다.

해시 테이블 주요 작업

Hashtable의 주요 작업은 가져오기, 컬렉션에 삽입 및 제거입니다. 이 세 가지 작업은 다음과 같습니다.
  • 객체 get(객체 키)은 키를 지정한 객체의 값을 반환합니다. 해당 키가 없으면 null을 반환합니다.
  • Object put(객체 키, 객체 값)은 지정된 키를 지정된 값에 매핑합니다. 키도 값도 null일 수 없습니다.
  • Object remove(객체 키)는 해시 테이블에서 항목(키 및 해당 값)을 제거합니다.
다른 중요한 작업:
  • int size()는 해시 테이블의 항목 수량을 반환합니다.
  • boolean contains(Object value) 지정된 값이 해시 테이블에 있는지 확인합니다. 그렇다면 메서드는 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • boolean containsValue(Object value)는 지정된 값이 해시 테이블에 있는지 확인합니다. 그렇다면 메서드는 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • void clear()는 해시 테이블에서 모든 항목을 제거합니다.
  • boolean containsKey(객체 키)는 지정된 키가 해시 테이블에 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • 부울 isEmpty()는 해시 테이블이 비어 있으면 true를 반환하고 하나 이상의 키가 포함되어 있으면 false를 반환합니다.
  • void rehash()는 해시 테이블의 크기를 늘리고 모든 키를 다시 해시합니다.

해시 테이블 구현, Java 코드:

학생 클래스를 만들어 봅시다 :

import java.util.Date;
public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }

   @Override
   public int hashCode(){
       //TODO: check for nulls
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
다음은 Java Hashtable 예제입니다. Student 클래스 의 두 개체를 해시 테이블에 넣은 다음 일부를 제거하고 일부 매개 변수를 확인하겠습니다.

public class HashTableExample {
   public static void main(String[] args) {
 
       Hashtable<Student, Integer> myHTable = new Hashtable<>();
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       myHTable.put(john,1);
       myHTable.put(sarah1,0);
       System.out.println(myHTable.get(john));
       System.out.println(myHTable.isEmpty());
       System.out.println(myHTable.size());
       System.out.println(myHTable.contains(1));
       myHTable.remove(john);
       System.out.println(myHTable.contains(0));
       System.out.println(myHTable.contains(1));
       System.out.println(myHTable.containsKey(sarah1));
   }
}
프로그램 실행 결과는 다음과 같습니다.

1
false
2
true
true
false
true

HashMap 대 Hashtable

  • Hashtable은 Java의 HashMap과 유사합니다. 가장 중요한 차이점은 Hashtable은 동기화되지만 HashMap은 동기화되지 않는다는 것입니다. 따라서 Hashtable은 동기화 때문에 HashMap보다 느립니다.
  • 동기화 문제를 제외하고 Hashtable은 null을 값이나 키로 사용하는 것을 허용하지 않습니다. HashMap은 하나의 null 키와 여러 개의 null 값을 허용합니다.
  • Hashtable은 Dictionary 클래스를 상속하고 HashMap은 AbstractMap 클래스를 상속합니다.
  • HashMap은 Iterator에 의해 순회됩니다. Hashtable은 Iterator뿐 아니라 Enumerator로도 탐색할 수 있습니다.

Java 해시 테이블 예제(Hashtable 대 HashMap null 키)

다음은 HashMapHashtable 에서 키와 값으로 사용되는 null을 보여주는 조각 코드입니다.

// Null key Java hashtable example and hashmap example  

try{
      System.out.println("Hashtable");
      Hashtable hashTable = new Hashtable();
      hashTable.put(null, new Object());
    }catch(Exception ex){
      ex.printStackTrace();
    }
    System.out.println("HashMap");
    HashMap hashMap = new HashMap();
    hashMap.put(null, new Object());
    System.out.println("as you see no exceptions with null key in HashMap");
  }
이 조각을 포함하는 프로그램을 실행한 결과:

java.lang.NullPointerException
	at java.base/java.util.Hashtable.put(Hashtable.java:480)
	at Character.main(Character.java:58)
HashMap
as you see no exceptions with null key in HashMap

결론

실제 프로젝트에서 Hashtable을 자주 사용하지는 않지만 이전 프로젝트에서 이 데이터 구조를 쉽게 만날 수 있습니다. 어쨌든 적어도 인터뷰를 위해서는 Java의 데이터 구조와 작동 방식을 이해하는 것이 중요합니다. 일반적으로 유사성 때문에 Hashtable 대신 HashMap 개체가 사용됩니다. HashMap이 더 효과적이며(동기화되지 않음) null을 키로 가질 수 있습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION