/* * Copyright (c) 2014, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.utilities.collection; import java.util.Map; import java.util.NoSuchElementException; /** * Instances of the class {@code MultipleMapIterator} implement an iterator that can be used to * sequentially access the entries in multiple maps. */ public class MultipleMapIterator<K, V> implements MapIterator<K, V> { /** * The iterators used to access the entries. */ private MapIterator<K, V>[] iterators; /** * The index of the iterator currently being used to access the entries. */ private int iteratorIndex = -1; /** * The current iterator, or {@code null} if there is no current iterator. */ private MapIterator<K, V> currentIterator; /** * Initialize a newly created iterator to return the entries from the given maps. * * @param maps the maps containing the entries to be iterated */ @SuppressWarnings("unchecked") public MultipleMapIterator(Map<K, V>[] maps) { int count = maps.length; iterators = new MapIterator[count]; for (int i = 0; i < count; i++) { iterators[i] = new SingleMapIterator<K, V>(maps[i]); } } @Override public K getKey() { if (currentIterator == null) { throw new NoSuchElementException(); } return currentIterator.getKey(); } @Override public V getValue() { if (currentIterator == null) { throw new NoSuchElementException(); } return currentIterator.getValue(); } @Override public boolean moveNext() { if (iteratorIndex < 0) { if (iterators.length == 0) { currentIterator = null; return false; } if (advanceToNextIterator()) { return true; } else { currentIterator = null; return false; } } if (currentIterator.moveNext()) { return true; } else if (advanceToNextIterator()) { return true; } else { currentIterator = null; return false; } } @Override public void setValue(V newValue) { if (currentIterator == null) { throw new NoSuchElementException(); } currentIterator.setValue(newValue); } /** * Under the assumption that there are no more entries that can be returned using the current * iterator, advance to the next iterator that has entries. * * @return {@code true} if there is a current iterator that has entries */ private boolean advanceToNextIterator() { iteratorIndex++; while (iteratorIndex < iterators.length) { MapIterator<K, V> iterator = iterators[iteratorIndex]; if (iterator.moveNext()) { currentIterator = iterator; return true; } iteratorIndex++; } return false; } }