2017-08-24 87 views
5

我有一个Map。TreeMap iterator.remove()修改最后一个条目

Map<Integer,String> map = ... 

该变换图具有n个元素(让对本示例中,这些9)

map.put(1,"one"); 
    map.put(2,"two"); 
    map.put(3,"three"); 
    map.put(4,"four"); 
    map.put(5,"five"); 
    map.put(6,"six"); 
    map.put(7,"seven"); 
    map.put(8,"eigth"); 
    map.put(9,"nine"); 

现在我想遍历这个地图,并且使用迭代除去第n个元件。

private void remove(int num, final Map<Integer, String> map) { 

    Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator(); 
    Map.Entry<Integer,String> entry; 
    while(it.hasNext()){ 

    entry = it.next(); 

    if(Integer.valueOf(num).equals(entry.getKey())){ 
     it.remove(); 
     System.out.println(entry.getValue()); 
     // vs 
     // System.out.println(entry.getValue()); 
     // it.remove(); 
    } 
    } 
} 

从javadoc,我假设,删除的语义是明确的。

但根据地图的实现 - 即HashMap的VS TreeMap的是有差别是否it.remove()entry.getValue()后或做过

为包含HashMap map = new HashMap<>()行为是

... 
remove(4, map); //output: four 
//or 
remove(5, map); //output: five 

为TreeMap的map = new TreeMap<>()的行为是一样的,当我后移除迭代器当前条目我曾访问过它:

System.out.println(entry.getValue()); 
it.remove(); 

结果在

remove(4, map); //output: four 
//or 
remove(5, map); //output: five 

到目前为止好,但如果我之前删除元素我访问入口:

it.remove(); 
System.out.println(entry.getValue()); 

输出是意外

remove(4, map); //output: five !!! 
//or 
remove(5, map); //output: five ok 

显然,TreeMapit.remove()修改Entries,因为TreeMapEntries组成,迭代器实际返回地图的实际元素。取决于树中的当前位置,入口点的内部引用指向下一个或当前(已删除)元素。

但我不确定这是一个错误还是这是故意的。如果后者是这种情况,我想知道背后的理由吗?

编辑:的TreeMap iterator.remove()

+0

我不明白你在任何一个地图中描述的行为......你使用的是什么Java版本?如果在remove()之前和之后输出条目的值会发生什么? – daniu

+0

jdk1.8.0_121 ...它可以用只有3个条目的TreeMap(1,2,3)重现,删除中间元素(2)。但它没有出现在HashMap –

+0

之前和之后打印出来的结果是“两个,三个” –

回答