[학습 시리즈]HashMap
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 언어의 특성 을 더욱 나 타 냈 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Java] 객체지향 프로그래밍 - 역사와 클래스실제 사물의 속성과 기능을 분석한 다음, 데이터(변수)와 함수로 정희하여 실제 세계를 컴퓨터 속에 옮겨 놓은 것과 같은 가상 세계를 구현하고 이 가상세계에서 모의실험을 함으로써 많은 시간과 비용을 절약할 수 있게 되...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.