Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>What you describe (having an iterator-local Map.Entry object and reusing it for all <code>next()</code> return values) is one possible Map implementation, and I think some special-purpose maps are using this.</p> <p>For example, the implementation of <code>EnumMap.entrySet().iterator()</code> (here the version from OpenJDK, 1.6.0_20) simply uses the iterator object itself as the Entry object returned by the <code>next()</code> method:</p> <pre><code>/** * Since we don't use Entry objects, we use the Iterator itself as entry. */ private class EntryIterator extends EnumMapIterator&lt;Map.Entry&lt;K,V&gt;&gt; implements Map.Entry&lt;K,V&gt; { public Map.Entry&lt;K,V&gt; next() { if (!hasNext()) throw new NoSuchElementException(); lastReturnedIndex = index++; return this; } public K getKey() { checkLastReturnedIndexForEntryUse(); return keyUniverse[lastReturnedIndex]; } public V getValue() { checkLastReturnedIndexForEntryUse(); return unmaskNull(vals[lastReturnedIndex]); } public V setValue(V value) { checkLastReturnedIndexForEntryUse(); V oldValue = unmaskNull(vals[lastReturnedIndex]); vals[lastReturnedIndex] = maskNull(value); return oldValue; } // equals, hashCode, toString private void checkLastReturnedIndexForEntryUse() { if (lastReturnedIndex &lt; 0) throw new IllegalStateException("Entry was removed"); } } </code></pre> <p>This is possible, since the <a href="http://download.oracle.com/javase/6/docs/api/index.html?java/util/Map.Entry.html" rel="noreferrer"><code>Map.Entry</code> specification</a> states (emphasis by me):</p> <blockquote> <p>A map entry (key-value pair). The <code>Map.entrySet</code> method returns a collection-view of the map, whose elements are of this class. The only way to obtain a reference to a map entry is from the iterator of this collection-view. <strong>These <code>Map.Entry</code> objects are valid only for the duration of the iteration</strong>; more formally, the behavior of a map entry is undefined if the backing map has been modified after the entry was returned by the iterator, except through the setValue operation on the map entry.</p> </blockquote> <p>If you want all entries at once, you'll have to use <code>map.entrySet().toArray()</code>, which may create immutable copies of the entries.</p> <hr> <p>Here some more observations about the default maps (all in OpenJDK 1.6.0_20 as found in Ubuntu's <code>openjdk6-source</code> package):</p> <ul> <li><p>The general purpose maps <code>HashMap</code> and <code>TreeMap</code> (as well as the legacy <code>Hashtable</code>) are already using some kind of <code>Entry</code> objects as part of their internal structure (the table or tree), so they simple let these objects implement Map.Entry and return them. They are not created on the fly by the Iterator.</p> <p>The same is valid for <code>WeakHashMap</code> (where having an <code>Entry</code> object in a strong reference does not avoid its key to get garbage-collected, if I understand right - but as long as you don't call <code>next()</code> on the iterator, the iterator holds the key in the current entry).</p></li> <li><p><code>IdentityHashMap</code> is internally using a simple <code>Object[]</code>, with alternating key and value, so no entry objects here, too, and thus also a reusing of the iterator as entry.</p></li> <li><p><code>ConcurrentSkipListMap</code> is using Node objects which do not implement anything, so its iterators return <code>new AbstractMap.SimpleImmutableEntry&lt;K,V&gt;(n.key, v);</code>. This implies you can't use their <code>setValue()</code> method, as explained in the class documentation:</p> <blockquote> <p>All <code>Map.Entry</code> pairs returned by methods in this class and its views represent snapshots of mappings at the time they were produced. They do not support the <code>Entry.setValue</code> method. (Note however that it is possible to change mappings in the associated map using <code>put</code>, <code>putIfAbsent</code>, or <code>replace</code>, depending on exactly which effect you need.) </p> </blockquote></li> <li><p><code>ConcurrentHashMap</code> internally uses a <code>HashEntry</code> class analogously to the HashMap, but this does not implement anything. Additionally, there is an internal class <code>WriteThroughEntry</code> (extending <code>AbstractMap.SimpleEntry</code>), whose <code>setValue()</code> method delegates to the <code>put</code> method of the map. The iterator returns new objects of this <code>WriteThroughEntry</code> class.</p></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload