2013-06-18 1 views
0

이 코드는 다른 사람이 작성한 것으로 이해하기 힘듭니다. 논리이 코드 뒤에 나오는 설명 - Java

그것은 잘 작동하고 올바른 결과를 생성하지만 난 어떻게 작동하는지 이해할 수 없었다됩니다

package you; 

import clowns.Clown; 
import clowns.Volkswagen; 

public class You { 
static int counter = 0; 
static Volkswagen vw = new Volkswagen(); 

public static void main(String args[]) { 
    vw.add(new RecursiveClown()); 
    vw.done(); 
} 

static class RecursiveClown extends Clown { 
    public int hashCode() { 
     if (++counter < 20) { 
      vw.add(new RecursiveClown()); 
     } 
     return super.hashCode(); 
    } 
} 
} 

분명히 RecursiveClown가도 그 hashcode() 기능

그럼 어떻게 어디서든 호출되지 않는 것을 이해할 수 없었다 그것을 작동 시키면 RecursiveClown 개체를 추가하십시오.

또한

super.hashCode();을 반환 왜 다른 클래스는 위 코드에서 참조되었다가있다. 이 두 클래스의

package clowns; 

import java.util.HashSet; 
import java.util.Set; 

public class Volkswagen { 
private static final int CAPACITY = 5; 
private Set<Clown> clowns = new HashSet<Clown>(); 

public synchronized void add(Clown clown) { 
    if (clowns.size() >= CAPACITY) { 
     throw new IllegalStateException("I'm full"); 
    } else { 
     clowns.add(clown); 
    } 
} 

public synchronized void done() { 
    if (clowns.size() == 20) { 
     // The goal is to reach this line 
     System.out.println("I'm a Volkswagen with 20 clowns!"); 
    } 
} 
} 

출력은 다음과 같습니다 I'm a Volkswagen with 20 clowns!

하지만 '폭스 바겐'의 add() 방법에

clowns.size() 

를 인쇄 할 때마다 항상이

clowns.size() == 20 
를 비교 오는 방법 다음 0을 반환

이 사실이라고 평가합니까?

답변

0

코드는 .hashCode()에 의존하는 HashSet에 의존합니다.

HashSet에 요소를 삽입 할 때 Set 구현은 추가 할 요소에서 먼저 .hashCode()을 호출하여 요소의 고유성을 결정합니다. 해시 코드가 다른 경우에만 .equals()이 고려됩니다.

Object의 하나이기 때문에 super.hashCode()가 반환됩니다. Clown은이를 무시하지 않습니다.

RecursiveClownClown이므로, 을 Clowns로 더할 수 있습니다. 하나를 추가 할 때 counter 자체가 HashMap 의해 백업되는 제

1

Set<Clowns>HashSet이며 도달 할 때까지, .hashCode()는 바겐 또 다른 재귀 광대를 추가한다. 기본적으로 Set<Clowns>에 개체를 추가하면 HashMap.put()이 호출됩니다.

HashMap.put() 제공된 개체의 hashCode() 메서드를 호출하십시오. 그런 이유로 명시 적 호출없이 개체의 hashCode() 메서드가 호출됩니다.

2

폭스 바겐의 용량이 허용하는 것보다 많은 광대가 들어있는 이유는 광대가 추가되는 방식 때문입니다.

이 방법 Volkswagen.add()의 선

clowns.add(clown); 

내에 필수적이다. 먼저 광대의 hashCode을 호출하여 추가 한 다음 내부 구조에 추가합니다. hashCode 재귀 다시 Volkswagen.add()를 호출하기 때문에,이 시점에서 광대 아직 HashSet 제 (내부 데이터 구조의 배면)에 따라서 size() 0을 반환

용량있어서 Volkswagen.add()의 시작에 도달하지이 방법을 추가하지만되지 이 메서드를 종료 할 때만 (실제로 광대가 HashSet에 실제로 추가되기 때문에). FGE 언급했듯이이 광대 # 1에 추가되기 전에, 광대 # 2의 Volkswagan.add 함수가 호출되는 것을 의미하는 추가되기 전에

1

함수 HashSet.add는, 오브젝트의 hashcode를 확인한다.

해시 코드 함수에 20 회의 심층 반복이있을 때까지 다음 작업이 수행되고 한 번 종료되면 20 개의 광대가 모두 한 번에 추가됩니다.