Iterating the Keys

Here is the Map interface:

public interface Map<K, V> {
  boolean put(K key, V value);  // stores value under key, replacing any old value;
                                // returns true if the key was not present before
  V get(K key);                 // returns the value stored under key, or null if key is absent
  boolean remove(K key);        // removes key and its value if key is present;
                                // returns true if the map changed
  boolean containsKey(K key);   // returns true if key is in the map
  int size();                   // returns the number of key-value pairs in the map
}

Here is the Iterator<T> interface:

public interface Iterator<T> {
  boolean hasNext();  // returns true if there are items left to return; does not advance
  T next();           // returns the next item and advances past it;
                      // throws NoSuchElementException if there are no items left
}

ArrayMap<K, V> stores its pairs in a backing array of entries, at indices 0 through size - 1:

public class ArrayMap<K, V> implements Map<K, V> {
  private Entry<K, V>[] arr;  // the backing array
  private int size;           // how many pairs the map holds

  private static class Entry<K, V> {
    K key;
    V value;
  }

  // the Map operations are already implemented
}

LinkedMap<K, V> stores its pairs in a singly linked list, one node per pair:

public class LinkedMap<K, V> implements Map<K, V> {
  private Node<K, V> head;  // the first node, or null when empty
  private int size;         // how many pairs the map holds

  private static class Node<K, V> {
    K key;
    V value;
    Node<K, V> next;
  }

  // the Map operations are already implemented
}
Solution

Map extends Iterable<K>:

public interface Map<K, V> extends Iterable<K> {
  // the five operations as before
}

Every implementing class must now provide a method iterator() that returns an Iterator<K>.

Solution
@Override
public Iterator<K> iterator() {
  return new KeyIterator();
}

private class KeyIterator implements Iterator<K> {
  private int cursor = 0;  // index of the entry whose key comes next

  @Override
  public boolean hasNext() {
    return cursor < size;
  }

  @Override
  public K next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    return arr[cursor++].key;
  }
}
Solution
@Override
public Iterator<K> iterator() {
  return new KeyIterator();
}

private class KeyIterator implements Iterator<K> {
  private Node<K, V> current = head;  // node whose key comes next

  @Override
  public boolean hasNext() {
    return current != null;
  }

  @Override
  public K next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    K key = current.key;
    current = current.next;
    return key;
  }
}