001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.collections.iterators; 018 019 import java.util.Iterator; 020 import java.util.Map; 021 022 import org.apache.commons.collections.MapIterator; 023 import org.apache.commons.collections.ResettableIterator; 024 025 /** 026 * Implements a <code>MapIterator</code> using a Map entrySet. 027 * Reverse iteration is not supported. 028 * <pre> 029 * MapIterator it = map.mapIterator(); 030 * while (it.hasNext()) { 031 * Object key = it.next(); 032 * Object value = it.getValue(); 033 * it.setValue(newValue); 034 * } 035 * </pre> 036 * 037 * @since Commons Collections 3.0 038 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ 039 * 040 * @author Stephen Colebourne 041 */ 042 public class EntrySetMapIterator implements MapIterator, ResettableIterator { 043 044 private final Map map; 045 private Iterator iterator; 046 private Map.Entry last; 047 private boolean canRemove = false; 048 049 /** 050 * Constructor. 051 * 052 * @param map the map to iterate over 053 */ 054 public EntrySetMapIterator(Map map) { 055 super(); 056 this.map = map; 057 this.iterator = map.entrySet().iterator(); 058 } 059 060 //----------------------------------------------------------------------- 061 /** 062 * Checks to see if there are more entries still to be iterated. 063 * 064 * @return <code>true</code> if the iterator has more elements 065 */ 066 public boolean hasNext() { 067 return iterator.hasNext(); 068 } 069 070 /** 071 * Gets the next <em>key</em> from the <code>Map</code>. 072 * 073 * @return the next key in the iteration 074 * @throws java.util.NoSuchElementException if the iteration is finished 075 */ 076 public Object next() { 077 last = (Map.Entry) iterator.next(); 078 canRemove = true; 079 return last.getKey(); 080 } 081 082 //----------------------------------------------------------------------- 083 /** 084 * Removes the last returned key from the underlying <code>Map</code>. 085 * <p> 086 * This method can be called once per call to <code>next()</code>. 087 * 088 * @throws UnsupportedOperationException if remove is not supported by the map 089 * @throws IllegalStateException if <code>next()</code> has not yet been called 090 * @throws IllegalStateException if <code>remove()</code> has already been called 091 * since the last call to <code>next()</code> 092 */ 093 public void remove() { 094 if (canRemove == false) { 095 throw new IllegalStateException("Iterator remove() can only be called once after next()"); 096 } 097 iterator.remove(); 098 last = null; 099 canRemove = false; 100 } 101 102 //----------------------------------------------------------------------- 103 /** 104 * Gets the current key, which is the key returned by the last call 105 * to <code>next()</code>. 106 * 107 * @return the current key 108 * @throws IllegalStateException if <code>next()</code> has not yet been called 109 */ 110 public Object getKey() { 111 if (last == null) { 112 throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()"); 113 } 114 return last.getKey(); 115 } 116 117 /** 118 * Gets the current value, which is the value associated with the last key 119 * returned by <code>next()</code>. 120 * 121 * @return the current value 122 * @throws IllegalStateException if <code>next()</code> has not yet been called 123 */ 124 public Object getValue() { 125 if (last == null) { 126 throw new IllegalStateException("Iterator getValue() can only be called after next() and before remove()"); 127 } 128 return last.getValue(); 129 } 130 131 /** 132 * Sets the value associated with the current key. 133 * 134 * @param value the new value 135 * @return the previous value 136 * @throws UnsupportedOperationException if setValue is not supported by the map 137 * @throws IllegalStateException if <code>next()</code> has not yet been called 138 * @throws IllegalStateException if <code>remove()</code> has been called since the 139 * last call to <code>next()</code> 140 */ 141 public Object setValue(Object value) { 142 if (last == null) { 143 throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()"); 144 } 145 return last.setValue(value); 146 } 147 148 //----------------------------------------------------------------------- 149 /** 150 * Resets the state of the iterator. 151 */ 152 public void reset() { 153 iterator = map.entrySet().iterator(); 154 last = null; 155 canRemove = false; 156 } 157 158 /** 159 * Gets the iterator as a String. 160 * 161 * @return a string version of the iterator 162 */ 163 public String toString() { 164 if (last != null) { 165 return "MapIterator[" + getKey() + "=" + getValue() + "]"; 166 } else { 167 return "MapIterator[]"; 168 } 169 } 170 171 }