TreeMap wierdness

This one has me baffled

public static void main( String[] args )
{
	Map<Integer, String> map = new TreeMap<Integer, String>();

	String[] strings = new String[] { "foo", "bar", "baz", "flub" };

	for( int i = 0; i < strings.length; i++ )
	{
		map.put( new Integer( i ), strings[ i ] );
	}

	boolean fail = true;

	String toRemove = fail ? strings[ 1 ] : strings[ 2 ];

	Iterator<Map.Entry<Integer, String>> iter = map.entrySet().iterator();
	while( iter.hasNext() )
	{
		final Map.Entry<Integer, String> e = iter.next();
		final int index = e.getKey().intValue();
		final String s = e.getValue();

		if( s == toRemove )
		{
			iter.remove();

			if( index != e.getKey().intValue() )
			{
				System.out.println( "wat. " + index + " != "
						+ e.getKey().intValue() );
			}
			else
			{
				System.out.println( "as expected" );
			}
		}
	}
}

If “fail” is true, the Map.Entry somehow changes its key value when I remove it from the map. I don’t feel that this is the correct behaviour and it’s certainly not made clear enough in the docs if it is intended, but I can sort of see how it might happen.

However, if “fail” is false, then everything works as I expect even though the only difference is which entry is removed.

To put it mildly, ???

Someone put me out of my puzzled misery and point me to the docs that explain why this is so.

I think it’s fair to assume that after you remove an entry, the values in it are ‘undefined’. That the TreeMap reuses the entry should not have been the case, as it reveals the implementation in the public API, but the alternative would have been not to reuse it, which might cause a serious performance impact.

I base this on absolutely nothing.

I think you’re right.

A cautionary tale then. Always assume that the key value will change, store it at the first opportunity.

I do believe that this is somewhere in the javadocs. It always claims that entry etc are “backed” by the map and changes in the map are reflected in the “collection” instances that are backed by the map.

However i can’t find where in the Java doc right now.