Implementing entries()

Here is the Map interface. A map is iterable over its keys, and entries() returns a separate Iterable over its key–value pairs. Each pair is handed back as a Map.Entry:

public interface Map<K, V> extends Iterable<K> {
  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

  Iterable<Map.Entry<K, V>> entries();  // returns an Iterable over the key-value pairs

  interface Entry<K, V> {
    K key();    // returns the key of this pair
    V value();  // returns the value of this pair
  }
}

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
}

LinkedMap<K, V> implements Map<K, V> with 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;

    Node(K key, V value) {
      this.key = key;
      this.value = value;
    }
  }

  // the Map operations and the key iterator are already implemented

  @Override
  public Iterable<Map.Entry<K, V>> entries() {
    return null;  // TODO
  }
}
Solution

Node implements Map.Entry<K, V>:

private static class Node<K, V> implements Map.Entry<K, V> {
  K key;
  V value;
  Node<K, V> next;

  Node(K key, V value) {
    this.key = key;
    this.value = value;
  }

  @Override
  public K key() {
    return key;
  }

  @Override
  public V value() {
    return value;
  }
}

entries() returns an Entries object. Entries is an Iterable whose iterator() creates an EntryIterator:

@Override
public Iterable<Map.Entry<K, V>> entries() {
  return new Entries();
}

private class Entries implements Iterable<Map.Entry<K, V>> {
  @Override
  public Iterator<Map.Entry<K, V>> iterator() {
    return new EntryIterator();
  }
}

private class EntryIterator implements Iterator<Map.Entry<K, V>> {
  private Node<K, V> current = head;  // node that comes next

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

  @Override
  public Map.Entry<K, V> next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    Node<K, V> node = current;
    current = current.next;
    return node;
  }
}
Solution

The caller receives each node as a Map.Entry<K, V>, which has only key() and value(). Node is a private class of LinkedMap, so code outside the map cannot name it, cast to it, or reach its fields.

Solution

The traversal is : it makes calls to next(), and each is . The auxiliary space is : the iterator holds one node reference and hands back nodes that already exist, so it copies nothing.