HashMap에서 사용하려는 사용자 정의 클래스 MarioState가 있습니다. 클래스는 마리오 게임의 상태 공간에서 가능한 상태를 나타냅니다. 다음은 MarioState 클래스의 단순화 된 버전입니다.HashMap의 ContainsKey가 사용자 정의 클래스와 함께 키로 작동하지 않습니다.
내 HashMap에서이 상태를 저장하고 싶습니다. 그러나 MarioState의 재산은 두 개의 MarioState를 비교할 때 고려해야 할 사항입니다. 예를 들어 하나의 MarioState가 true로 설정된 30 개의 거리와 다른 MarioState의 stuck 속성이 true이지만 다른 거리 값 (예 : 20)으로 설정된 경우 동일한 MarioState가 여전히 동일하게 간주되어야합니다.
내 HashMap에서 작동하도록 알고있다. (내가 InteliJ IDE에서 자동으로 생성하도록함으로써) .equals() 및 .hashcode() 메소드를 구현해야한다. 그것은 그들의에 따라하지 말아야 할 때
공용 클래스 MarioState {
// Tracking the distance Mario has moved. private int distance; private int lastDistance; // To keep track of if Mario is stuck or not. private int stuckCount; private boolean stuck; public MarioState(){ stuckCount = 0; stuck = false; distance = 0; lastDistance = 0; } public void update(Environment environment){ // Computing the distance int tempDistance = environment.getEvaluationInfo().distancePassedPhys; distance = tempDistance - lastDistance; lastDistance = tempDistance; // If Mario hasn't moved for over 25 turns then this means he is stuck. if(distance == 0){ stuckCount++; } else { stuckCount = 0; stuck = false; } if(stuckCount > 25){ stuck = true; } } public float calculateReward(){ float reward = 0f; reward += distance * 2; if(stuck){ reward += -20; } return reward; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MarioState that = (MarioState) o; if (stuck != that.stuck) return false; return true; } @Override public int hashCode() { return (stuck ? 1 : 0); }
은}
문제는 코드를 실행할 때 키 중 일부는 다른 간주됩니다 그러나입니다. equals() 및 .hashcode() 함수를 호출합니다. 무엇이 이것을 일으킬 수 있습니까? 내가 뭔가 잊었 니?
HashMap의에서 상태를 삽입 할 때 사용되는 코드 (필요한 경우 추가 정보를 제공 할 수있다),
public float[] getActionsQValues(MarioState state){
if(!table.containsKey(state)) {
float[] initialQvalues = getInitialQvalues(state);
table.put(state, initialQvalues);
return initialQvalues;
}
return table.get(state);
}
스크린 샷을 내가 디버그 모드에있어 서로 다른 값을 가진 두 개의 키가 포함 된 내 테이블을 표시하지만 키 자체는 동일합니다 (그러나 HashMap에서는 다른 것으로 간주됩니다).
지도에 요소를 추가 한 후에'stuck' *을 변경 하시겠습니까? 그것은 분명히 그것을 설명 할 것입니다. –
@JonSkeet 짧은 답변 : 예. 답변 : 현재 상태를 변수로 추적하는 다른 클래스가 있습니다. MarioState에서 업데이트 메소드를 호출하고 상태가 변경되면 수정하는 모든 시간 단계. 그런 다음, 수정 된 상태를 HashMap의 상태로 검사하는 getActionsQValues가 호출됩니다. 상태가 HashMap에 완전히 새로운 경우 (즉, HashMap에 아직 생성되지 않은 속성의 고유 한 조합) 만 입력해야합니다. –
짧은 대답 : 키의 해시 코드가 추가 된 후에 변경되지 않는다는 HashMap 가정이 깨졌습니다. 키가있는지도를 갖는 것이 매우 이상합니다. 어쨌든 단일 '부울'값은 정직합니다. –