2009-11-04 7 views
0

자바 해시 테이블 직렬화에 대한 논란이있는 것으로 보이지만 사용중인 논리에서 오류를 찾을 수 없습니다. 여기에 내가, 뭘 오전입니다Java Hashtable 및 serialization

Hashtable sspsrpData = new Hashtable(); 
for(int i=0;i<Constants.secondayStructures.length;i++) { 
    SecondaryStructures ss = (SecondaryStructures)(data.get(Constants.secondayStructures[i])); 
    sspsrpData.put(Constants.secondayStructures[i], new SecStrucPSRP(ss.getSecStruct(),ss.getLengthCounts())); 
} 
    FileOutputStream fos = null; 
    ObjectOutputStream out = null; 
    fos = new FileOutputStream(Constants.sspsrpData); 
    out = new ObjectOutputStream(fos); 
    out.writeObject(sspsrpData); 

이렇게 형성된 해시 테이블을 serialize해야 또한 해시 테이블에 3 키 - 값 쌍을 넣어해야이 코드 조각. 지금은이 코드 조각에 의해 다시 다른 프로그램을 가져 오지하려고 할 때 :

FileInputStream fis = null; 
ObjectInputStream in = null; 
fis = new FileInputStream(Constants.sspsrpData); 
in = new ObjectInputStream(fis); 
ssPsrp = (Hashtable)in.readObject(); 

결과 해시 테이블은이 키 - 값 쌍을 가지고있다. 해시 테이블의 수는 3이지만 해시 테이블에서 2 개의 키 값 쌍만 볼 수 있습니다. 뭐가 잘못 됐는지 이해가 안돼 !!

누군가 내가 잘못 가고 있다고 지적 할 수 있습니까?

감사합니다 좋은 하루, Santhosh

+0

언급 한 다른 프로그램 : 동일한 Java 버전과 완전히 동일한 코드를 사용하고 있습니까? – sfussenegger

+0

안녕하세요 ..그렇습니다. 다른 프로그램은 첫 번째 프로그램에 의해 직렬화 된 것을 deserialize하려고합니다. 오브젝트 직렬화 프로그램을 살펴보면 3 개의 오브젝트가 있지만, 직렬화 프로그램을 살펴보면 개수가 3이된다고하더라도 2 개의 오브젝트 만 포함됩니다. – user202385

+0

어떤 특정 장소를 조사해야합니까 .. ?? – user202385

답변

0

예 .. 모든 3 키 - 값 쌍은 동일 이상한 것은 (문자열 - SecStrucPSRP 객체). 모든 객체는 직렬화 가능합니다. 해시 테이블을 deserialize하는 동안 만 그 중 2가 액세스 할 수 있습니다 ..

1

어쩌면 Constants.secondayStructures[0] .equals(Constants.secondayStructures[1]) 또는 Constants.secondayStructures[1] .equals(Constants.secondayStructures[2])

sspsrpData.size() 전에이 직렬화하기 전에 좋은 크기 을 가지고 확실하게, 개체를 직렬화보십시오.

+0

나도 그렇게 생각하고 디버깅을 시작했다. 솔루션을 찾지는 못했지만 흥미로운 관찰을 찾지 못했다. 키를 추가하는 동안 키 중 하나가 교체되고 있으므로 초기 해시 테이블에 10 개의 값이 채워지고 첫 번째 추가는 6 그리고 그 다음 추가는 4에 있었다. 마지막 추가는 4시에 다시 추가되고 있었다. 나는 그 일이 어떻게 일어나는지 모른다. 열쇠는 확실히 다릅니다. 나는 hashtable 대신 hashmap을 사용하여 해보 았는데 완벽하게 잘 작동한다. Thnaks for reply .. 만약 누군가가 똑같은 문제를 겪고 있다면, 나는 그들이 동일한 디버깅 증상을 가지고 있는지 알고 싶다. – user202385

+0

여러 다른 키가 저장되는 것이 정상이다. 동일한 위치에서, 위치는 해시 함수에 의해 결정된다. 여러 개의 키가 같은 위치에 저장되면 항목 (키 + 값)이 연결됩니다. 지정된 키의 값을 취득하기 위해서, 키는 해시되어 보일 위치를 찾아 내, 그 키는 지정된 위치의 키와 비교됩니다 (equals와). 그래서 해시 코드와 같음은 일관성이 있고 시간이 지남에 따라 안정적이어야합니다 ... – pgras

1

HashMap은 "열린 해싱"을 사용합니다. 즉, hashCode 메서드가 동일한 고유 번호를 생성하는 두 개의 다른 항목을 삽입하면 (가끔 발생 함) 해시 테이블은 두 항목을 연결된 목록과 같은 위치에 삽입함으로써이 충돌을 해결합니다. 디버그 모드에서 해시 테이블 내의 한 항목을 살펴보십시오. "next"라는 이름의 속성도 있습니다. 이것은 해시 테이블 내의 동일한 위치에있는 하나의 추가 항목에 대한 포인터입니다. 즉, HashMap 구현은 테이블의 모든 위치에서 "연결된 목록"을 관리합니다. 하나 이상의 항목이 같은 위치에 저장되면 hashCode 메서드가 동일한 값을 계산하는 경우 관련 해시 테이블 위치는 이러한 모든 항목을 연결된 목록에 저장합니다.

해시 테이블의 serialization 문제는 해시 테이블이 항목을 내부적으로 다른 위치에 저장한다는 것입니다. 관련된 항목은 직렬화 전에 다른 테이블 위치를 갖습니다. deserialization 후에는 다른 위치에 저장되기 때문에이 항목을 다시 찾을 수 없습니다. 이것이 Sun/Oracle의 의도인지는 모르겠습니다. 그게 버그 야? 나는 똑같은 문제가있다. 나는 어떤 해결책을 찾고있다.

+0

HashMaps/Hashtables의 직렬화 및지도의 직렬화되지 않은 버전에서 동일한 항목을 추출하면 내 잘못이 있습니다. 그러나 맵의 주요 객체는 hashCode 메소드를 덮어 썼습니다. 그리고이 구현은 잘못되었습니다. 보십시오 [링크] (http://www.devx.com/tips/Tip/12934). 비 직렬화 해시 맵으로부터 동일한 열쇠 오브젝트를 취득 할 수 없다고하는 문제에 직면했을 경우, 열쇠 오브젝트의 hashCode 구현을 체크 할 필요가 있습니다. –

0

직렬화 주제에서 매우 중요한 점입니다. Hashtable 저장소 키/값 쌍이 항목이있는 버킷에 있습니다. 물통 위치 자체는 키의 hashCode()에서 만들어집니다. 따라서, hashCode() 함수가 오버라이드되지 않은 객체 (즉, Object.hashCode()을 사용하는 객체)이면,이 해시 코드 값의 생성은 JVM에서 JVM으로 또는 한 프로그램에서 다른 것으로 실행할 수 있습니다. 거의 확실하게, 그것의 직렬화가 해제되었을 때, 그 객체는 동일하지 않고 그 인스턴스의 새로운 참조가되어, 직렬화되고있는 시점이 다른 hashCode()가되어, 결과적으로 스트림의 파손이되거나, 단지 객체가 발견되지 않습니다. 이 작업을 수행하거나 키의 기본 데이터 유형을 제공 할 수 있습니다. 따라서 Integer가 키가 될 수 있으며 Hashtable.put(2, myValueObj)을 사용할 수 있습니다. → java가 정수 primitive를 autoboxes하기 때문입니다.