hashCode 와 equals 소스 코드 분석 및 응용

5504 단어
레 퍼 런 스
1. JDK 1.8 소스 코드
2. 장 효 상 시리즈
3. - 솔 휘
장면
hashCode 는 도대체 어떻게 이해 합 니까?
분석 하 다.
기본 이론
집합 에서 구체 적 인 요 소 를 어떻게 찾 습 니까?집합 이 만 개의 요소 로 구성 된다 고 가정 하면 하나 가 처음부터 끝까지 순서대로 조 회 를 비교 하면 너무 느 립 니 다. - 물론 이것 도 검색 방법 입 니 다.자주 사용 하 는 검색 방법 은 크게 세 가지 로 나 눌 수 있 습 니 다. 순서 구조 검색 유형, 그리고 이 진 트 리 를 바탕 으로 하 는 분기 구조 조회 유형 과 Hash Table 을 바탕 으로 하 는 hash 검색 유형 입 니 다.우 리 는 아래 hash table 의 작성 과정 과 조회 방식 을 간단하게 이해 합 니 다. 여기 서 Hash 함수 가 hash (int 라 고 가정 합 니 다.  key) = key mod 13 (주: 13 은 hash table 의 표 길 이 를 대표 하고 자바 의 집합 류 크기 에 대응 합 니 다).
hash table 구조 과정
키워드
Hash 함수 로 주소 계산 하기
주소.
7
7 mod 13
7
4
4 mod 13
4
134
134 mod 13
4
14
14 mod 13
1
구 성 된 hash table
주소.
0
1
2
3
4
5
6
7
8
9
10
11
12
키워드
 
14
 
 
4、134
 
 
7
 
 
 
 
 
위의 표 에서 알 수 있 듯 이 키워드 가 다 르 고 hash 후의 주 소 는 같 습 니 다.이상 의 인식 이 있 으 면 hash 함 수 를 이해 하 는 것 이 어렵 지 않 습 니 다.
hashCode 분석 및 메모리 누 출 시 뮬 레이 션
  • Object 와 String 의 hashCode () 와 equals () 분석
  •      /**
    	 *      :        (      ),                                (  
    	 *             )
    	 *      :
    	 *    1、if(A.equals(B))  then     B.hashCode() == A.hashCode // Object A,B
    	 *    2、A、B  equals,A、B        。             hash      hash         
    	 *    “ However, the
             *     programmer should be aware that producing distinct integer results
             *     for unequal objects may improve the performance of hash tables.”        “  ”   。
    	 */
    	 public native int hashCode();
    	 
    	 /**
    	  *    :          -  a   b         (       ),a.equals(b)     true
    	  *    :
    	  *  1、x.equals(y) <=> y.equals(x)
    	  *  2、   equals    ,      hashCode   -   hashCode     !
    	  */
    	  public boolean equals(Object obj)
    	  {
    	        return (this == obj);
    	    }
     
    	  /**
    	     * String   hashCode  
    	     *     :s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] // s[i] :        , n:   
    	     *
    	     * @return  a hash code value for this object.
    	     */
    	    public int hashCode()
    	    {
    	        int h = hash; //     
    	        if (h == 0 && value.length > 0)
    	        {
    	            char val[] = value; //  String str = "abc" ,  val [] = ['a','b','c']
    	            for (int i = 0; i < value.length; i++)
    	            {
    	                h = 31 * h + val[i];
    	            }
    	            hash = h;
    	        }
    	        return h;
    	    }
    	    
    	    /**
    	     *   :         
    	     *   :          ASC    ,      
    	     */
    	    public boolean equals(Object anObject)
    	    {
    	        if (this == anObject) { return true;}
    	        if (anObject instanceof String)
    	        {
    	            String anotherString = (String)anObject;
    	            int n = value.length;
    	            if (n == anotherString.value.length) 
    	            {
    	                char v1[] = value;
    	                char v2[] = anotherString.value;
    	                int i = 0;
    	                while (n-- != 0)
    	                {
    	                    if (v1[i] != v2[i])
    	                        return false;
    	                    i++;
    	                }
    	                return true;
    	            }
    	        }
    	        return false;
    	    }
  • HashSet 기반 메모리 누 출 시 뮬 레이 션
  • Hash 의 집합 대상 (eg, HashSet) 을 기반 으로 삽입 후 구성원 변수의 값 을 바 꾸 면 메모리 가 누 출 될 수 있 습 니 다.여기 서 HashSet 에서 add (E) 를 예 로 들 어 Hash 검색 과정 (add 와 reove 의 소스 코드 분석 후속 보충) 을 거시적 으로 분석 합 니 다.전제: Hash table 은 이미 1 을 구성 하고 대상 의 키워드 (즉 hashCode 값) 를 가 져 왔 습 니 다. 2. 키워드 에 따라 hash 함 수 를 대 입 하여 대상 의 메모리 주 소 를 계산 합 니 다. 3. 주소 에 따라 해당 대상 이 관련 메모리 영역 에 존재 하 는 지 비교 합 니까?false 를 되 돌려 주 고 삽입 에 실 패 했 습 니 다. 그렇지 않 으 면 성공 합 니 다.
    /**
     * @author pengyucheng
     *     
     */
    public class ReflectPoint
    {
    	private int x;
    	private int y;
    	public ReflectPoint(int x, int y)
    	{
    		super();
    		this.x = x;
    		this.y = y;
    	}
    	@Override
    	public int hashCode() 
    	{
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + x;
    		result = prime * result + y;
    		return result;
    	}
    	@Override
    	public boolean equals(Object obj)
    	{
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		ReflectPoint other = (ReflectPoint) obj;
    		if (x != other.x)
    			return false;
    		if (y != other.y)
    			return false;
    		return true;
    	}
    	public int getX() {
    		return x;
    	}
    	public void setX(int x) {
    		this.x = x;
    	}
    	public int getY() {
    		return y;
    	}
    	public void setY(int y) {
    		this.y = y;
    	}
    }
                    /**
    		 *       
    		 */
    		HashSet<ReflectPoint> collection2 = new HashSet<ReflectPoint>();
    		ReflectPoint rp11= new ReflectPoint(1,2);
    		ReflectPoint rp22= new ReflectPoint(2,2);
    		ReflectPoint rp44= new ReflectPoint(2,2);
    		collection2.add(rp11);
    		collection2.add(rp22);
    		collection2.add(rp44);
    		System.out.println(collection2.size());// size = 2
    		
    		rp22.setX(9);
    		/*
    		 *rp22     x       => hashCode    =>           =>     ,       
    		 *     , remove   -           !
    		 /
    		collection2.remove(rp22);// 
    		System.out.println(collection2.size()); // size = 2 => rp22            =>     

    총결산
    역할: hashCode 는 Hash table 류 를 기반 으로 하 는 대상 의 검색 효율 을 높이 기 위해 존재 합 니 다.
    규칙: equals 방법 을 다시 쓸 때 hashCode 방법 을 동기 화 해 야 합 니 다.hash 클래스 집합 에 요 소 를 추가 한 후 요소 의 값 을 수정 하지 마 십시오. 그렇지 않 으 면 메모리 가 누 출 될 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기