1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.iterators;
  17. import java.util.Iterator;
  18. import java.util.Map;
  19. import org.apache.commons.collections.MapIterator;
  20. import org.apache.commons.collections.ResettableIterator;
  21. /**
  22. * Implements a <code>MapIterator</code> using a Map entrySet.
  23. * Reverse iteration is not supported.
  24. * <pre>
  25. * MapIterator it = map.mapIterator();
  26. * while (it.hasNext()) {
  27. * Object key = it.next();
  28. * Object value = it.getValue();
  29. * it.setValue(newValue);
  30. * }
  31. * </pre>
  32. *
  33. * @since Commons Collections 3.0
  34. * @version $Revision: 1.7 $ $Date: 2004/02/18 00:59:50 $
  35. *
  36. * @author Stephen Colebourne
  37. */
  38. public class EntrySetMapIterator implements MapIterator, ResettableIterator {
  39. private final Map map;
  40. private Iterator iterator;
  41. private Map.Entry last;
  42. private boolean canRemove = false;
  43. /**
  44. * Constructor.
  45. *
  46. * @param map the map to iterate over
  47. */
  48. public EntrySetMapIterator(Map map) {
  49. super();
  50. this.map = map;
  51. this.iterator = map.entrySet().iterator();
  52. }
  53. //-----------------------------------------------------------------------
  54. /**
  55. * Checks to see if there are more entries still to be iterated.
  56. *
  57. * @return <code>true</code> if the iterator has more elements
  58. */
  59. public boolean hasNext() {
  60. return iterator.hasNext();
  61. }
  62. /**
  63. * Gets the next <em>key</em> from the <code>Map</code>.
  64. *
  65. * @return the next key in the iteration
  66. * @throws java.util.NoSuchElementException if the iteration is finished
  67. */
  68. public Object next() {
  69. last = (Map.Entry) iterator.next();
  70. canRemove = true;
  71. return last.getKey();
  72. }
  73. //-----------------------------------------------------------------------
  74. /**
  75. * Removes the last returned key from the underlying <code>Map</code>.
  76. * <p>
  77. * This method can be called once per call to <code>next()</code>.
  78. *
  79. * @throws UnsupportedOperationException if remove is not supported by the map
  80. * @throws IllegalStateException if <code>next()</code> has not yet been called
  81. * @throws IllegalStateException if <code>remove()</code> has already been called
  82. * since the last call to <code>next()</code>
  83. */
  84. public void remove() {
  85. if (canRemove == false) {
  86. throw new IllegalStateException("Iterator remove() can only be called once after next()");
  87. }
  88. iterator.remove();
  89. last = null;
  90. canRemove = false;
  91. }
  92. //-----------------------------------------------------------------------
  93. /**
  94. * Gets the current key, which is the key returned by the last call
  95. * to <code>next()</code>.
  96. *
  97. * @return the current key
  98. * @throws IllegalStateException if <code>next()</code> has not yet been called
  99. */
  100. public Object getKey() {
  101. if (last == null) {
  102. throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
  103. }
  104. return last.getKey();
  105. }
  106. /**
  107. * Gets the current value, which is the value associated with the last key
  108. * returned by <code>next()</code>.
  109. *
  110. * @return the current value
  111. * @throws IllegalStateException if <code>next()</code> has not yet been called
  112. */
  113. public Object getValue() {
  114. if (last == null) {
  115. throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()");
  116. }
  117. return last.getValue();
  118. }
  119. /**
  120. * Sets the value associated with the current key.
  121. *
  122. * @param value the new value
  123. * @return the previous value
  124. * @throws UnsupportedOperationException if setValue is not supported by the map
  125. * @throws IllegalStateException if <code>next()</code> has not yet been called
  126. * @throws IllegalStateException if <code>remove()</code> has been called since the
  127. * last call to <code>next()</code>
  128. */
  129. public Object setValue(Object value) {
  130. if (last == null) {
  131. throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
  132. }
  133. return last.setValue(value);
  134. }
  135. //-----------------------------------------------------------------------
  136. /**
  137. * Resets the state of the iterator.
  138. */
  139. public void reset() {
  140. iterator = map.entrySet().iterator();
  141. last = null;
  142. canRemove = false;
  143. }
  144. /**
  145. * Gets the iterator as a String.
  146. *
  147. * @return a string version of the iterator
  148. */
  149. public String toString() {
  150. if (last != null) {
  151. return "MapIterator[" + getKey() + "=" + getValue() + "]";
  152. } else {
  153. return "MapIterator[]";
  154. }
  155. }
  156. }