2017-11-19 6 views
0

사용자 지정 직렬화 기에서 이전에 본 개체를 추적하기 위해 ID 해시 맵을 사용하고 있습니다. while 루프를 사용하여 맵의 항목을 반복합니다. 메서드를 호출하는 동안 addAllFields 개체가지도의 키 집합에 추가 될 수 있습니다. 일부 디버깅을 한 후 내 iterator.hasNext() 반환 사실을 알고있는 경우에도 그 개체가 마지막 루프 본문 실행 이후 맵에 추가 된 것으로 나타났습니다. 여기서 내가 뭘 잘못하고 있니?Java List 반복자가 IdentityHashMap에서 작동하지 않습니다.

public Document serialize(Object obj) throws Exception { 
    reset(); 
    addToMap(obj); 
    Set<Object> keys = map.keySet(); 
    Iterator<Object> iterator = keys.iterator(); 
    while(iterator.hasNext()) { 
     Object key = iterator.next(); 
     Element objectElement = createObjectElement(key.getClass().getName(), map.get(key)); 
     addAllFields(objectElement, key); 
     document.getRootElement().addContent(objectElement); 
    } 
    return document; 
} 
+2

* "내가 뭘 잘못 했니? ? "iterati 동안지도 수정하기 ng. ['keySet()']의 Javadoc (https://docs.oracle.com/javase/9/docs/api/java/util/IdentityHashMap.html#keySet--)은 다음과 같이 말합니다 : *지도가 ** 인 경우 집합에 대한 반복 **이 진행되는 동안 수정 된 반복 결과는 ** undefined **입니다. * – Andreas

+0

이러한 정의되지 않은 동작이없는 다른 해시지도가 있습니까? –

+1

['ConcurrentHashMap'] (https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ConcurrentHashMap.html). ['keySet()']의 Javadoc (https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ConcurrentHashMap.html#keySet--)은 다음과 같이 말합니다 : * 뷰의 반복자와 spliterators [weakly consistent] (https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/package-summary.html#Weakly) * 즉, 구성 요소가 존재할 때 요소를 통과하도록 보장됩니다. 정확히 한 번, 그리고 건설 후 수정 사항을 반영 할 수는 있지만 보장 할 수는 없습니다. – Andreas

답변

0

당신은 ListIterator를 사용할 필요가 있고, 당신도 추가 요소를 반복하려는 경우 당신은 역으로 모든 일을 수행해야합니다 당신은 당신이 키 집합 포장해야 할 수도 있습니다

ListIterator<Object> iter = keys.listIterator(keys.size()); 
while (iter.hasPrevious()){ 
    Object prev=iter.previous(); 
    // do your Element creation here 
    // then use the iter.add() method 
    iter.add(/*new object*/); 
} 

NB ListIterator를 모두 지원하지 않는 다른 컬렉션 유형이며 #addAllFields()에 인수로 iter를 전달해야합니다. 키 집합 대신 입력 집합을 반복해야 할 수도 있습니다

+0

당신의 잠재적 솔루션에 감사드립니다. 그것은 일종의 정렬을 보장하는 다른 맵 구현을 사용해야하기 때문일 수 있습니까? 링크 해시 맵은 어떻습니까? –

+1

정확한 해결책은 처리 할 때 #addAllFields()에 추가 한 항목이 추가 항목을 추가 할 수 있는지 여부에 달려 있다고 생각하십니까? 나는 당신이 뭔가를 떠나는 반복 동안 추가를 지원하는 Map 구현이 있다고 생각하지 않는다. List > l = new ArrayList <> (map.entrySet()); // V는지도 값 유형입니다. ListIterator > iter = l.listIterator(); 그리고 내 대답은 위와 같습니다. 결국'map' 업데이트가 필요하다면'l'에서 새로운 항목을 추가해야합니다. – SteveR