[학습 시리즈]HashMap

5732 단어 OOP알고리즘
더 읽 기
HashCode 에서 출발 하여 HashMap 과 자신의 HashCode 를 다시 쓰 는 방법 을 소개 합 니 다.
자바 에서 대상 에 대한 조작 은 인용 에 기초 한 것 으로 알려 져 있다.우리 가 한 그룹의 대상 을 조작 해 야 할 때,이 인용 을 받 는 용기 가 필요 하 다.평소에 우리 가 가장 자주 사용 하 는 것 은 배열 이다.자바 에 서 는 많은 작업 을 수행 하기 위해 대상 배열 을 정의 할 수 있 습 니 다.그러나 배열 의 길 이 는 고정 되 어 있 습 니 다.만약 우리 가 더욱 유연 한 해결 방안 이 필요 하 다 면 어떻게 해 야 합 니까?
자 바 는 이 문 제 를 해결 하기 위해 container classes 를 제공 했다.container classes 는 두 부분 을 포함한다.Collection 과 Map.그들의 구 조 는 이렇다.
본 고 는 HashMap 을 중점적으로 소개 한다.우선 맵 이 무엇 인지 소개 하 겠 습 니 다.배열 에서 우 리 는 배열 아래 표 시 를 통 해 그 내용 을 색인 하 는 것 이 고,Map 에서 우 리 는 대상 을 통 해 대상 을 색인 하 며,색인 에 사용 하 는 대상 을 key 라 고 하 며,대응 하 는 대상 을 value 라 고 합 니 다.아래 문장에서 구체 적 으로 설명 할 예 가 있 을 것 이다.
해시 맵 과 트 리 맵 이 어떤 차이 가 있 는 지 살 펴 보 자.HashMap 은 hashcode 를 통 해 그 내용 을 빠르게 찾 습 니 다.TreeMap 의 모든 요 소 는 일정한 순 서 를 유지 하고 있 습 니 다.질서 있 는 결 과 를 얻 으 려 면 TreeMap(HashMap 에서 요소 의 배열 순 서 는 고정 되 지 않 습 니 다)을 사용 해 야 합 니 다.
다음은 본문의 주제 에 들 어가 야 한다.먼저 예 를 들 어 HashMap 을 어떻게 사용 하 는 지 설명 하 세 요.
import java.util.*;
public class Exp1 {
     public static void main(String[] args){
          HashMap h1=new HashMap();
          Random r1=new Random();   
          for(int i=0;i<1000;i++){
               Integer t=new Integer(r1.nextInt(20));
               if(h1.containsKey(t))
                    ((Ctime)h1.get(t)).count++;
               else
                    h1.put(t, new Ctime());
          }
          System.out.println(h1);
     }
}
class Ctime{
     int count=1;
     public String toString(){
          return Integer.toString(count);
     }
}
HashMap 에 서 는 get()을 통 해 value 를 가 져 오고 put()를 통 해 value 를 삽입 하 며 ContainKey()는 대상 이 존재 하 는 지 확인 합 니 다.이 를 통 해 알 수 있 듯 이 Array List 의 조작 에 비해 HashMap 은 key 를 통 해 그 내용 을 색인 하 는 것 을 제외 하고 다른 측면 에서 차이 가 크 지 않다.
앞에서 소개 한 바 와 같이 HashMap 은 HashCode 를 바탕 으로 하 는 것 으로 모든 대상 의 초 클래스 Object 에 HashCode()방법 이 있 지만 equals 방법 과 마찬가지 로 모든 상황 에 적용 되 지 않 습 니 다.그러면 우 리 는 자신의 HashCode()방법 을 다시 써 야 합 니 다.다음은 다음 과 같은 예 를 들 겠 습 니 다.

import java.util.*;
public class Exp2 {
     public static void main(String[] args){
          HashMap h2=new HashMap();
          for(int i=0;i<10;i++)
               h2.put(new Element(i), new Figureout());
          System.out.println("h2:");
          System.out.println("Get the result for Element:");
          Element test=new Element(5);
          if(h2.containsKey(test))
               System.out.println((Figureout)h2.get(test));
          else
               System.out.println("Not found");
     }
}

class Element{
     int number;
     public Element(int n){
          number=n;
     } 
}

class Figureout{
     Random r=new Random();
     boolean possible=r.nextDouble()>0.5;
     public String toString(){
          if(possible)
               return "OK!";
          else
               return "Impossible!";
     }
}
 

이 예 에서 Element 는 색인 대상 인 Figureout,즉 Element 는 key 이 고 Figureout 은 value 이다.Figureout 에서 무 작위 로 부동 소수점 을 생 성 합 니 다.0.5 보다 크 면"OK!"를 인쇄 합 니 다.그렇지 않 으 면"Impossible!"을 인쇄 합 니 다.이후 Element(3)에 대응 하 는 Figureout 결 과 를 살 펴 본다.
그 결과 당신 이 몇 번 을 운행 하 든 얻 은 결 과 는'Not found'였 다.색인 Element(3)은 HashMap 에 없 는 것 이다.그 럴 리 가 있 겠 습 니까?
이 유 는 천천히 말 해 야 한다.Element 의 HashCode 방법 은 Object 에서 계승 되 고 Object 의 HashCode 방법 으로 돌아 오 는 HashCode 는 현재 주소 에 대응 된다.즉,서로 다른 대상 에 대해 내용 이 똑 같 더 라 도 HashCode()로 돌아 오 는 값 이 다르다 는 것 이다.이렇게 하 는 것 은 사실상 우리 의 의 도 를 위배 하 는 것 이다.HashMap 을 사용 할 때 같은 내용 의 대상 색인 을 이용 하여 같은 대상 을 얻 으 려 면 HashCode()가 이 때 같은 값 을 되 돌려 줄 수 있어 야 하기 때 문 입 니 다.위의 예 에서 우 리 는 new Element(i=5)와 Element test=new Element(5)가 같 기 를 기대 합 니 다.실제로 이것 은 두 개의 서로 다른 대상 입 니 다.비록 그들의 내용 은 같 지만 메모리 에 있 는 주 소 는 다 릅 니 다.그래서 자 연 스 럽 게 위의 절 차 는 우리 가 구상 한 결 과 를 얻 지 못 한다.다음 Element 클래스 에 대한 변경 사항 은 다음 과 같 습 니 다.

class Element{
     int number;
     public Element(int n){
          number=n;
     } 
     public int hashCode(){
          return number;
     }
     public boolean equals(Object o){
          return (o instanceof Element) && (number==((Element)o).number);
     }
} 


여기 서 Element 는 Object 의 hashCode()와 equals()방법 을 덮어 씁 니 다.hashCode()를 덮어 서 number 의 값 을 hashcode 로 되 돌려 줍 니 다.같은 내용 의 대상 에 게 hashcode 도 같 습 니 다.equals()를 덮어 쓰 는 것 은 HashMap 에서 두 키 가 같은 지 판단 할 때 결 과 를 의미 있 게 하기 위해 서 입 니 다.수 정 된 프로그램 실행 결 과 는 다음 과 같 습 니 다.
h2:
Get the result for Element:
Impossible!
기억 하 세 요:HashMap 을 효과적으로 사용 하려 면 HashCode()에 다시 써 야 합 니 다.
그리고 HashCode()를 다시 쓰 는 두 가지 원칙 이 있 습 니 다.
서로 다른 대상 에 게 유일한 hashcode 를 만 들 필요 가 없습니다.HashCode 방법 으로 get()이 put()를 넣 을 수 있 는 내용 만 있 으 면 됩 니 다.즉'불 위 일 원칙'이다.
hashcode 를 만 드 는 알고리즘 은 가능 한 한 hashcode 의 값 을 분산 시 키 고 많은 hashcode 가 한 범위 에 집중 하지 않 으 면 HashMap 의 성능 을 향상 시 킬 수 있 습 니 다.분산 원칙'이다.
두 번 째 원칙 의 구체 적 인 원인 에 대해 관심 있 는 사람 은 Bruce Eckel 의 을 참고 할 수 있 습 니 다.그곳 에 HashMap 내부 실현 원리 에 대한 소개 가 있 으 니 더 이상 언급 하지 않 겠 습 니 다.
이 두 가지 원칙 을 파악 하면 HashMap 으로 자신의 프로그램 을 잘 작성 할 수 있 습 니 다.주의 하 시 겠 습 니까?자바.lang.Object 에서 제공 하 는 세 가지 방법:clone(),equals()와 hashCode()는 전형 적 이지 만 적용 되 지 않 는 경우 가 많 습 니 다.대상 의 주소 로 만 결 과 를 얻 을 수 있 습 니 다.이것 은 우리 가 자신의 프로그램 에서 그것들 을 다시 써 야 한다.사실 자바 라 이브 러 리 에서 도 수천 만 개의 이런 방법 을 다시 썼 다.대상 을 대상 으로 하 는 다 형 성-커버 를 이용 하여 자바 의 디자이너 는 자바 의 구 조 를 우아 하 게 구축 하고 자바 가 순수한 OOP 언어의 특성 을 더욱 나 타 냈 다.
  


  

  
  
    
  

  
  

좋은 웹페이지 즐겨찾기