Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      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 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.base.Objects;
     21 import com.google.common.base.Preconditions;
     22 import static com.google.common.base.Preconditions.checkArgument;
     23 import static com.google.common.base.Preconditions.checkState;
     24 import static com.google.common.collect.Multisets.setCountImpl;
     25 
     26 import java.io.IOException;
     27 import java.io.ObjectInputStream;
     28 import java.io.ObjectOutputStream;
     29 import java.io.Serializable;
     30 import java.util.AbstractCollection;
     31 import java.util.AbstractMap;
     32 import java.util.AbstractSequentialList;
     33 import java.util.AbstractSet;
     34 import java.util.Collection;
     35 import static java.util.Collections.unmodifiableList;
     36 import java.util.HashSet;
     37 import java.util.Iterator;
     38 import java.util.List;
     39 import java.util.ListIterator;
     40 import java.util.Map;
     41 import java.util.Map.Entry;
     42 import java.util.NoSuchElementException;
     43 import java.util.Set;
     44 
     45 import javax.annotation.Nullable;
     46 
     47 /**
     48  * An implementation of {@code ListMultimap} that supports deterministic
     49  * iteration order for both keys and values. The iteration order is preserved
     50  * across non-distinct key values. For example, for the following multimap
     51  * definition: <pre>   {@code
     52  *
     53  *   Multimap<K, V> multimap = LinkedListMultimap.create();
     54  *   multimap.put(key1, foo);
     55  *   multimap.put(key2, bar);
     56  *   multimap.put(key1, baz);}</pre>
     57  *
     58  * ... the iteration order for {@link #keys()} is {@code [key1, key2, key1]},
     59  * and similarly for {@link #entries()}. Unlike {@link LinkedHashMultimap}, the
     60  * iteration order is kept consistent between keys, entries and values. For
     61  * example, calling: <pre>   {@code
     62  *
     63  *   map.remove(key1, foo);}</pre>
     64  *
     65  * changes the entries iteration order to {@code [key2=bar, key1=baz]} and the
     66  * key iteration order to {@code [key2, key1]}. The {@link #entries()} iterator
     67  * returns mutable map entries, and {@link #replaceValues} attempts to preserve
     68  * iteration order as much as possible.
     69  *
     70  * <p>The collections returned by {@link #keySet} and {@link #asMap} iterate
     71  * through the keys in the order they were first added to the multimap.
     72  * Similarly, {@link #get}, {@link #removeAll}, and {@link #replaceValues}
     73  * return collections that iterate through the values in the order they were
     74  * added. The collections generated by {@link #entries}, {@link #keys}, and
     75  * {@link #values} iterate across the key-value mappings in the order they were
     76  * added to the multimap.
     77  *
     78  * <p>Keys and values may be null. All optional multimap methods are supported,
     79  * and all returned views are modifiable.
     80  *
     81  * <p>The methods {@link #get}, {@link #keySet}, {@link #keys}, {@link #values},
     82  * {@link #entries}, and {@link #asMap} return collections that are views of the
     83  * multimap. If the multimap is modified while an iteration over any of those
     84  * collections is in progress, except through the iterator's own {@code remove}
     85  * operation, the results of the iteration are undefined.
     86  *
     87  * <p>This class is not threadsafe when any concurrent operations update the
     88  * multimap. Concurrent read operations will work correctly. To allow concurrent
     89  * update operations, wrap your multimap with a call to {@link
     90  * Multimaps#synchronizedListMultimap}.
     91  *
     92  * @author Mike Bostock
     93  * @since 2010.01.04 <b>stable</b> (imported from Google Collections Library)
     94  */
     95 @GwtCompatible(serializable = true)
     96 public final class LinkedListMultimap<K, V>
     97     implements ListMultimap<K, V>, Serializable {
     98   /*
     99    * Order is maintained using a linked list containing all key-value pairs. In
    100    * addition, a series of disjoint linked lists of "siblings", each containing
    101    * the values for a specific key, is used to implement {@link
    102    * ValueForKeyIterator} in constant time.
    103    */
    104 
    105   private static final class Node<K, V> {
    106     final K key;
    107     V value;
    108     Node<K, V> next; // the next node (with any key)
    109     Node<K, V> previous; // the previous node (with any key)
    110     Node<K, V> nextSibling; // the next node with the same key
    111     Node<K, V> previousSibling; // the previous node with the same key
    112 
    113     Node(@Nullable K key, @Nullable V value) {
    114       this.key = key;
    115       this.value = value;
    116     }
    117 
    118     @Override public String toString() {
    119       return key + "=" + value;
    120     }
    121   }
    122 
    123   private transient Node<K, V> head; // the head for all keys
    124   private transient Node<K, V> tail; // the tail for all keys
    125   private transient Multiset<K> keyCount; // the number of values for each key
    126   private transient Map<K, Node<K, V>> keyToKeyHead; // the head for a given key
    127   private transient Map<K, Node<K, V>> keyToKeyTail; // the tail for a given key
    128 
    129   /**
    130    * Creates a new, empty {@code LinkedListMultimap} with the default initial
    131    * capacity.
    132    */
    133   public static <K, V> LinkedListMultimap<K, V> create() {
    134     return new LinkedListMultimap<K, V>();
    135   }
    136 
    137   /**
    138    * Constructs an empty {@code LinkedListMultimap} with enough capacity to hold
    139    * the specified number of keys without rehashing.
    140    *
    141    * @param expectedKeys the expected number of distinct keys
    142    * @throws IllegalArgumentException if {@code expectedKeys} is negative
    143    */
    144   public static <K, V> LinkedListMultimap<K, V> create(int expectedKeys) {
    145     return new LinkedListMultimap<K, V>(expectedKeys);
    146   }
    147 
    148   /**
    149    * Constructs a {@code LinkedListMultimap} with the same mappings as the
    150    * specified {@code Multimap}. The new multimap has the same
    151    * {@link Multimap#entries()} iteration order as the input multimap.
    152    *
    153    * @param multimap the multimap whose contents are copied to this multimap
    154    */
    155   public static <K, V> LinkedListMultimap<K, V> create(
    156       Multimap<? extends K, ? extends V> multimap) {
    157     return new LinkedListMultimap<K, V>(multimap);
    158   }
    159 
    160   private LinkedListMultimap() {
    161     keyCount = LinkedHashMultiset.create();
    162     keyToKeyHead = Maps.newHashMap();
    163     keyToKeyTail = Maps.newHashMap();
    164   }
    165 
    166   private LinkedListMultimap(int expectedKeys) {
    167     keyCount = LinkedHashMultiset.create(expectedKeys);
    168     keyToKeyHead = Maps.newHashMapWithExpectedSize(expectedKeys);
    169     keyToKeyTail = Maps.newHashMapWithExpectedSize(expectedKeys);
    170   }
    171 
    172   private LinkedListMultimap(Multimap<? extends K, ? extends V> multimap) {
    173     this(multimap.keySet().size());
    174     putAll(multimap);
    175   }
    176 
    177   /**
    178    * Adds a new node for the specified key-value pair before the specified
    179    * {@code nextSibling} element, or at the end of the list if {@code
    180    * nextSibling} is null. Note: if {@code nextSibling} is specified, it MUST be
    181    * for an node for the same {@code key}!
    182    */
    183   private Node<K, V> addNode(
    184       @Nullable K key, @Nullable V value, @Nullable Node<K, V> nextSibling) {
    185     Node<K, V> node = new Node<K, V>(key, value);
    186     if (head == null) { // empty list
    187       head = tail = node;
    188       keyToKeyHead.put(key, node);
    189       keyToKeyTail.put(key, node);
    190     } else if (nextSibling == null) { // non-empty list, add to tail
    191       tail.next = node;
    192       node.previous = tail;
    193       Node<K, V> keyTail = keyToKeyTail.get(key);
    194       if (keyTail == null) { // first for this key
    195         keyToKeyHead.put(key, node);
    196       } else {
    197         keyTail.nextSibling = node;
    198         node.previousSibling = keyTail;
    199       }
    200       keyToKeyTail.put(key, node);
    201       tail = node;
    202     } else { // non-empty list, insert before nextSibling
    203       node.previous = nextSibling.previous;
    204       node.previousSibling = nextSibling.previousSibling;
    205       node.next = nextSibling;
    206       node.nextSibling = nextSibling;
    207       if (nextSibling.previousSibling == null) { // nextSibling was key head
    208         keyToKeyHead.put(key, node);
    209       } else {
    210         nextSibling.previousSibling.nextSibling = node;
    211       }
    212       if (nextSibling.previous == null) { // nextSibling was head
    213         head = node;
    214       } else {
    215         nextSibling.previous.next = node;
    216       }
    217       nextSibling.previous = node;
    218       nextSibling.previousSibling = node;
    219     }
    220     keyCount.add(key);
    221     return node;
    222   }
    223 
    224   /**
    225    * Removes the specified node from the linked list. This method is only
    226    * intended to be used from the {@code Iterator} classes. See also {@link
    227    * LinkedListMultimap#removeAllNodes(Object)}.
    228    */
    229   private void removeNode(Node<K, V> node) {
    230     if (node.previous != null) {
    231       node.previous.next = node.next;
    232     } else { // node was head
    233       head = node.next;
    234     }
    235     if (node.next != null) {
    236       node.next.previous = node.previous;
    237     } else { // node was tail
    238       tail = node.previous;
    239     }
    240     if (node.previousSibling != null) {
    241       node.previousSibling.nextSibling = node.nextSibling;
    242     } else if (node.nextSibling != null) { // node was key head
    243       keyToKeyHead.put(node.key, node.nextSibling);
    244     } else {
    245       keyToKeyHead.remove(node.key); // don't leak a key-null entry
    246     }
    247     if (node.nextSibling != null) {
    248       node.nextSibling.previousSibling = node.previousSibling;
    249     } else if (node.previousSibling != null) { // node was key tail
    250       keyToKeyTail.put(node.key, node.previousSibling);
    251     } else {
    252       keyToKeyTail.remove(node.key); // don't leak a key-null entry
    253     }
    254     keyCount.remove(node.key);
    255   }
    256 
    257   /** Removes all nodes for the specified key. */
    258   private void removeAllNodes(@Nullable Object key) {
    259     for (Iterator<V> i = new ValueForKeyIterator(key); i.hasNext();) {
    260       i.next();
    261       i.remove();
    262     }
    263   }
    264 
    265   /** Helper method for verifying that an iterator element is present. */
    266   private static void checkElement(@Nullable Object node) {
    267     if (node == null) {
    268       throw new NoSuchElementException();
    269     }
    270   }
    271 
    272   /** An {@code Iterator} over all nodes. */
    273   private class NodeIterator implements Iterator<Node<K, V>> {
    274     Node<K, V> next = head;
    275     Node<K, V> current;
    276 
    277     public boolean hasNext() {
    278       return next != null;
    279     }
    280     public Node<K, V> next() {
    281       checkElement(next);
    282       current = next;
    283       next = next.next;
    284       return current;
    285     }
    286     public void remove() {
    287       checkState(current != null);
    288       removeNode(current);
    289       current = null;
    290     }
    291   }
    292 
    293   /** An {@code Iterator} over distinct keys in key head order. */
    294   private class DistinctKeyIterator implements Iterator<K> {
    295     final Set<K> seenKeys = new HashSet<K>(Maps.capacity(keySet().size()));
    296     Node<K, V> next = head;
    297     Node<K, V> current;
    298 
    299     public boolean hasNext() {
    300       return next != null;
    301     }
    302     public K next() {
    303       checkElement(next);
    304       current = next;
    305       seenKeys.add(current.key);
    306       do { // skip ahead to next unseen key
    307         next = next.next;
    308       } while ((next != null) && !seenKeys.add(next.key));
    309       return current.key;
    310     }
    311     public void remove() {
    312       checkState(current != null);
    313       removeAllNodes(current.key);
    314       current = null;
    315     }
    316   }
    317 
    318   /** A {@code ListIterator} over values for a specified key. */
    319   private class ValueForKeyIterator implements ListIterator<V> {
    320     final Object key;
    321     int nextIndex;
    322     Node<K, V> next;
    323     Node<K, V> current;
    324     Node<K, V> previous;
    325 
    326     /** Constructs a new iterator over all values for the specified key. */
    327     ValueForKeyIterator(@Nullable Object key) {
    328       this.key = key;
    329       next = keyToKeyHead.get(key);
    330     }
    331 
    332     /**
    333      * Constructs a new iterator over all values for the specified key starting
    334      * at the specified index. This constructor is optimized so that it starts
    335      * at either the head or the tail, depending on which is closer to the
    336      * specified index. This allows adds to the tail to be done in constant
    337      * time.
    338      *
    339      * @throws IndexOutOfBoundsException if index is invalid
    340      */
    341     public ValueForKeyIterator(@Nullable Object key, int index) {
    342       int size = keyCount.count(key);
    343       Preconditions.checkPositionIndex(index, size);
    344       if (index >= (size / 2)) {
    345         previous = keyToKeyTail.get(key);
    346         nextIndex = size;
    347         while (index++ < size) {
    348           previous();
    349         }
    350       } else {
    351         next = keyToKeyHead.get(key);
    352         while (index-- > 0) {
    353           next();
    354         }
    355       }
    356       this.key = key;
    357       current = null;
    358     }
    359 
    360     public boolean hasNext() {
    361       return next != null;
    362     }
    363 
    364     public V next() {
    365       checkElement(next);
    366       previous = current = next;
    367       next = next.nextSibling;
    368       nextIndex++;
    369       return current.value;
    370     }
    371 
    372     public boolean hasPrevious() {
    373       return previous != null;
    374     }
    375 
    376     public V previous() {
    377       checkElement(previous);
    378       next = current = previous;
    379       previous = previous.previousSibling;
    380       nextIndex--;
    381       return current.value;
    382     }
    383 
    384     public int nextIndex() {
    385       return nextIndex;
    386     }
    387 
    388     public int previousIndex() {
    389       return nextIndex - 1;
    390     }
    391 
    392     public void remove() {
    393       checkState(current != null);
    394       if (current != next) { // removing next element
    395         previous = current.previousSibling;
    396         nextIndex--;
    397       } else {
    398         next = current.nextSibling;
    399       }
    400       removeNode(current);
    401       current = null;
    402     }
    403 
    404     public void set(V value) {
    405       checkState(current != null);
    406       current.value = value;
    407     }
    408 
    409     @SuppressWarnings("unchecked")
    410     public void add(V value) {
    411       previous = addNode((K) key, value, next);
    412       nextIndex++;
    413       current = null;
    414     }
    415   }
    416 
    417   // Query Operations
    418 
    419   public int size() {
    420     return keyCount.size();
    421   }
    422 
    423   public boolean isEmpty() {
    424     return head == null;
    425   }
    426 
    427   public boolean containsKey(@Nullable Object key) {
    428     return keyToKeyHead.containsKey(key);
    429   }
    430 
    431   public boolean containsValue(@Nullable Object value) {
    432     for (Iterator<Node<K, V>> i = new NodeIterator(); i.hasNext();) {
    433       if (Objects.equal(i.next().value, value)) {
    434         return true;
    435       }
    436     }
    437     return false;
    438   }
    439 
    440   public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
    441     for (Iterator<V> i = new ValueForKeyIterator(key); i.hasNext();) {
    442       if (Objects.equal(i.next(), value)) {
    443         return true;
    444       }
    445     }
    446     return false;
    447   }
    448 
    449   // Modification Operations
    450 
    451   /**
    452    * Stores a key-value pair in the multimap.
    453    *
    454    * @param key key to store in the multimap
    455    * @param value value to store in the multimap
    456    * @return {@code true} always
    457    */
    458   public boolean put(@Nullable K key, @Nullable V value) {
    459     addNode(key, value, null);
    460     return true;
    461   }
    462 
    463   public boolean remove(@Nullable Object key, @Nullable Object value) {
    464     Iterator<V> values = new ValueForKeyIterator(key);
    465     while (values.hasNext()) {
    466       if (Objects.equal(values.next(), value)) {
    467         values.remove();
    468         return true;
    469       }
    470     }
    471     return false;
    472   }
    473 
    474   // Bulk Operations
    475 
    476   public boolean putAll(@Nullable K key, Iterable<? extends V> values) {
    477     boolean changed = false;
    478     for (V value : values) {
    479       changed |= put(key, value);
    480     }
    481     return changed;
    482   }
    483 
    484   public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
    485     boolean changed = false;
    486     for (Entry<? extends K, ? extends V> entry : multimap.entries()) {
    487       changed |= put(entry.getKey(), entry.getValue());
    488     }
    489     return changed;
    490   }
    491 
    492   /**
    493    * {@inheritDoc}
    494    *
    495    * <p>If any entries for the specified {@code key} already exist in the
    496    * multimap, their values are changed in-place without affecting the iteration
    497    * order.
    498    *
    499    * <p>The returned list is immutable and implements
    500    * {@link java.util.RandomAccess}.
    501    */
    502   public List<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {
    503     List<V> oldValues = getCopy(key);
    504     ListIterator<V> keyValues = new ValueForKeyIterator(key);
    505     Iterator<? extends V> newValues = values.iterator();
    506 
    507     // Replace existing values, if any.
    508     while (keyValues.hasNext() && newValues.hasNext()) {
    509       keyValues.next();
    510       keyValues.set(newValues.next());
    511     }
    512 
    513     // Remove remaining old values, if any.
    514     while (keyValues.hasNext()) {
    515       keyValues.next();
    516       keyValues.remove();
    517     }
    518 
    519     // Add remaining new values, if any.
    520     while (newValues.hasNext()) {
    521       keyValues.add(newValues.next());
    522     }
    523 
    524     return oldValues;
    525   }
    526 
    527   private List<V> getCopy(@Nullable Object key) {
    528     return unmodifiableList(Lists.newArrayList(new ValueForKeyIterator(key)));
    529   }
    530 
    531   /**
    532    * {@inheritDoc}
    533    *
    534    * <p>The returned list is immutable and implements
    535    * {@link java.util.RandomAccess}.
    536    */
    537   public List<V> removeAll(@Nullable Object key) {
    538     List<V> oldValues = getCopy(key);
    539     removeAllNodes(key);
    540     return oldValues;
    541   }
    542 
    543   public void clear() {
    544     head = null;
    545     tail = null;
    546     keyCount.clear();
    547     keyToKeyHead.clear();
    548     keyToKeyTail.clear();
    549   }
    550 
    551   // Views
    552 
    553   /**
    554    * {@inheritDoc}
    555    *
    556    * <p>If the multimap is modified while an iteration over the list is in
    557    * progress (except through the iterator's own {@code add}, {@code set} or
    558    * {@code remove} operations) the results of the iteration are undefined.
    559    *
    560    * <p>The returned list is not serializable and does not have random access.
    561    */
    562   public List<V> get(final @Nullable K key) {
    563     return new AbstractSequentialList<V>() {
    564       @Override public int size() {
    565         return keyCount.count(key);
    566       }
    567       @Override public ListIterator<V> listIterator(int index) {
    568         return new ValueForKeyIterator(key, index);
    569       }
    570       @Override public boolean removeAll(Collection<?> c) {
    571         return Iterators.removeAll(iterator(), c);
    572       }
    573       @Override public boolean retainAll(Collection<?> c) {
    574         return Iterators.retainAll(iterator(), c);
    575       }
    576     };
    577   }
    578 
    579   private transient Set<K> keySet;
    580 
    581   public Set<K> keySet() {
    582     Set<K> result = keySet;
    583     if (result == null) {
    584       keySet = result = new AbstractSet<K>() {
    585         @Override public int size() {
    586           return keyCount.elementSet().size();
    587         }
    588         @Override public Iterator<K> iterator() {
    589           return new DistinctKeyIterator();
    590         }
    591         @Override public boolean contains(Object key) { // for performance
    592           return keyCount.contains(key);
    593         }
    594       };
    595     }
    596     return result;
    597   }
    598 
    599   private transient Multiset<K> keys;
    600 
    601   public Multiset<K> keys() {
    602     Multiset<K> result = keys;
    603     if (result == null) {
    604       keys = result = new MultisetView();
    605     }
    606     return result;
    607   }
    608 
    609   private class MultisetView extends AbstractCollection<K>
    610       implements Multiset<K> {
    611 
    612     @Override public int size() {
    613       return keyCount.size();
    614     }
    615 
    616     @Override public Iterator<K> iterator() {
    617       final Iterator<Node<K, V>> nodes = new NodeIterator();
    618       return new Iterator<K>() {
    619         public boolean hasNext() {
    620           return nodes.hasNext();
    621         }
    622         public K next() {
    623           return nodes.next().key;
    624         }
    625         public void remove() {
    626           nodes.remove();
    627         }
    628       };
    629     }
    630 
    631     public int count(@Nullable Object key) {
    632       return keyCount.count(key);
    633     }
    634 
    635     public int add(@Nullable K key, int occurrences) {
    636       throw new UnsupportedOperationException();
    637     }
    638 
    639     public int remove(@Nullable Object key, int occurrences) {
    640       checkArgument(occurrences >= 0);
    641       int oldCount = count(key);
    642       Iterator<V> values = new ValueForKeyIterator(key);
    643       while ((occurrences-- > 0) && values.hasNext()) {
    644         values.next();
    645         values.remove();
    646       }
    647       return oldCount;
    648     }
    649 
    650     public int setCount(K element, int count) {
    651       return setCountImpl(this, element, count);
    652     }
    653 
    654     public boolean setCount(K element, int oldCount, int newCount) {
    655       return setCountImpl(this, element, oldCount, newCount);
    656     }
    657 
    658     @Override public boolean removeAll(Collection<?> c) {
    659       return Iterators.removeAll(iterator(), c);
    660     }
    661 
    662     @Override public boolean retainAll(Collection<?> c) {
    663       return Iterators.retainAll(iterator(), c);
    664     }
    665 
    666     public Set<K> elementSet() {
    667       return keySet();
    668     }
    669 
    670     public Set<Entry<K>> entrySet() {
    671       // TODO: lazy init?
    672       return new AbstractSet<Entry<K>>() {
    673         @Override public int size() {
    674           return keyCount.elementSet().size();
    675         }
    676 
    677         @Override public Iterator<Entry<K>> iterator() {
    678           final Iterator<K> keyIterator = new DistinctKeyIterator();
    679           return new Iterator<Entry<K>>() {
    680             public boolean hasNext() {
    681               return keyIterator.hasNext();
    682             }
    683             public Entry<K> next() {
    684               final K key = keyIterator.next();
    685               return new Multisets.AbstractEntry<K>() {
    686                 public K getElement() {
    687                   return key;
    688                 }
    689                 public int getCount() {
    690                   return keyCount.count(key);
    691                 }
    692               };
    693             }
    694             public void remove() {
    695               keyIterator.remove();
    696             }
    697           };
    698         }
    699       };
    700     }
    701 
    702     @Override public boolean equals(@Nullable Object object) {
    703       return keyCount.equals(object);
    704     }
    705 
    706     @Override public int hashCode() {
    707       return keyCount.hashCode();
    708     }
    709 
    710     @Override public String toString() {
    711       return keyCount.toString(); // XXX observe order?
    712     }
    713   }
    714 
    715   private transient Collection<V> valuesCollection;
    716 
    717   /**
    718    * {@inheritDoc}
    719    *
    720    * <p>The iterator generated by the returned collection traverses the values
    721    * in the order they were added to the multimap.
    722    */
    723   public Collection<V> values() {
    724     Collection<V> result = valuesCollection;
    725     if (result == null) {
    726       valuesCollection = result = new AbstractCollection<V>() {
    727         @Override public int size() {
    728           return keyCount.size();
    729         }
    730         @Override public Iterator<V> iterator() {
    731           final Iterator<Node<K, V>> nodes = new NodeIterator();
    732           return new Iterator<V>() {
    733             public boolean hasNext() {
    734               return nodes.hasNext();
    735             }
    736             public V next() {
    737               return nodes.next().value;
    738             }
    739             public void remove() {
    740               nodes.remove();
    741             }
    742           };
    743         }
    744       };
    745     }
    746     return result;
    747   }
    748 
    749   private transient Collection<Entry<K, V>> entries;
    750 
    751   /**
    752    * {@inheritDoc}
    753    *
    754    * <p>The iterator generated by the returned collection traverses the entries
    755    * in the order they were added to the multimap.
    756    *
    757    * <p>An entry's {@link Entry#getKey} method always returns the same key,
    758    * regardless of what happens subsequently. As long as the corresponding
    759    * key-value mapping is not removed from the multimap, {@link Entry#getValue}
    760    * returns the value from the multimap, which may change over time, and {@link
    761    * Entry#setValue} modifies that value. Removing the mapping from the
    762    * multimap does not alter the value returned by {@code getValue()}, though a
    763    * subsequent {@code setValue()} call won't update the multimap but will lead
    764    * to a revised value being returned by {@code getValue()}.
    765    */
    766   public Collection<Entry<K, V>> entries() {
    767     Collection<Entry<K, V>> result = entries;
    768     if (result == null) {
    769       entries = result = new AbstractCollection<Entry<K, V>>() {
    770         @Override public int size() {
    771           return keyCount.size();
    772         }
    773 
    774         @Override public Iterator<Entry<K, V>> iterator() {
    775           final Iterator<Node<K, V>> nodes = new NodeIterator();
    776           return new Iterator<Entry<K, V>>() {
    777             public boolean hasNext() {
    778               return nodes.hasNext();
    779             }
    780 
    781             public Entry<K, V> next() {
    782               final Node<K, V> node = nodes.next();
    783               return new AbstractMapEntry<K, V>() {
    784                 @Override public K getKey() {
    785                   return node.key;
    786                 }
    787                 @Override public V getValue() {
    788                   return node.value;
    789                 }
    790                 @Override public V setValue(V value) {
    791                   V oldValue = node.value;
    792                   node.value = value;
    793                   return oldValue;
    794                 }
    795               };
    796             }
    797 
    798             public void remove() {
    799               nodes.remove();
    800             }
    801           };
    802         }
    803       };
    804     }
    805     return result;
    806   }
    807 
    808   private class AsMapEntries extends AbstractSet<Entry<K, Collection<V>>> {
    809 
    810     // TODO: Override contains() and remove() for better performance.
    811 
    812     @Override public int size() {
    813       return keyCount.elementSet().size();
    814     }
    815 
    816     @Override public Iterator<Entry<K, Collection<V>>> iterator() {
    817       final Iterator<K> keyIterator = new DistinctKeyIterator();
    818       return new Iterator<Entry<K, Collection<V>>>() {
    819         public boolean hasNext() {
    820           return keyIterator.hasNext();
    821         }
    822 
    823         public Entry<K, Collection<V>> next() {
    824           final K key = keyIterator.next();
    825           return new AbstractMapEntry<K, Collection<V>>() {
    826             @Override public K getKey() {
    827               return key;
    828             }
    829 
    830             @Override public Collection<V> getValue() {
    831               return LinkedListMultimap.this.get(key);
    832             }
    833           };
    834         }
    835 
    836         public void remove() {
    837           keyIterator.remove();
    838         }
    839       };
    840     }
    841   }
    842 
    843   private transient Map<K, Collection<V>> map;
    844 
    845   public Map<K, Collection<V>> asMap() {
    846     Map<K, Collection<V>> result = map;
    847     if (result == null) {
    848       map = result = new AbstractMap<K, Collection<V>>() {
    849         Set<Entry<K, Collection<V>>> entrySet;
    850 
    851         @Override public Set<Entry<K, Collection<V>>> entrySet() {
    852           Set<Entry<K, Collection<V>>> result = entrySet;
    853           if (result == null) {
    854             entrySet = result = new AsMapEntries();
    855           }
    856           return result;
    857         }
    858 
    859         // The following methods are included for performance.
    860 
    861         @Override public boolean containsKey(@Nullable Object key) {
    862           return LinkedListMultimap.this.containsKey(key);
    863         }
    864 
    865         @SuppressWarnings("unchecked")
    866         @Override public Collection<V> get(@Nullable Object key) {
    867           Collection<V> collection = LinkedListMultimap.this.get((K) key);
    868           return collection.isEmpty() ? null : collection;
    869         }
    870 
    871         @Override public Collection<V> remove(@Nullable Object key) {
    872           Collection<V> collection = removeAll(key);
    873           return collection.isEmpty() ? null : collection;
    874         }
    875       };
    876     }
    877 
    878     return result;
    879   }
    880 
    881   // Comparison and hashing
    882 
    883   /**
    884    * Compares the specified object to this multimap for equality.
    885    *
    886    * <p>Two {@code ListMultimap} instances are equal if, for each key, they
    887    * contain the same values in the same order. If the value orderings disagree,
    888    * the multimaps will not be considered equal.
    889    */
    890   @Override public boolean equals(@Nullable Object other) {
    891     if (other == this) {
    892       return true;
    893     }
    894     if (other instanceof Multimap) {
    895       Multimap<?, ?> that = (Multimap<?, ?>) other;
    896       return this.asMap().equals(that.asMap());
    897     }
    898     return false;
    899   }
    900 
    901   /**
    902    * Returns the hash code for this multimap.
    903    *
    904    * <p>The hash code of a multimap is defined as the hash code of the map view,
    905    * as returned by {@link Multimap#asMap}.
    906    */
    907   @Override public int hashCode() {
    908     return asMap().hashCode();
    909   }
    910 
    911   /**
    912    * Returns a string representation of the multimap, generated by calling
    913    * {@code toString} on the map returned by {@link Multimap#asMap}.
    914    *
    915    * @return a string representation of the multimap
    916    */
    917   @Override public String toString() {
    918     return asMap().toString();
    919   }
    920 
    921   /**
    922    * @serialData the number of distinct keys, and then for each distinct key:
    923    *     the first key, the number of values for that key, and the key's values,
    924    *     followed by successive keys and values from the entries() ordering
    925    */
    926   private void writeObject(ObjectOutputStream stream) throws IOException {
    927     stream.defaultWriteObject();
    928     stream.writeInt(size());
    929     for (Entry<K, V> entry : entries()) {
    930       stream.writeObject(entry.getKey());
    931       stream.writeObject(entry.getValue());
    932     }
    933   }
    934 
    935   private void readObject(ObjectInputStream stream)
    936       throws IOException, ClassNotFoundException {
    937     stream.defaultReadObject();
    938     keyCount = LinkedHashMultiset.create();
    939     keyToKeyHead = Maps.newHashMap();
    940     keyToKeyTail = Maps.newHashMap();
    941     int size = stream.readInt();
    942     for (int i = 0; i < size; i++) {
    943       @SuppressWarnings("unchecked") // reading data stored by writeObject
    944       K key = (K) stream.readObject();
    945       @SuppressWarnings("unchecked") // reading data stored by writeObject
    946       V value = (V) stream.readObject();
    947       put(key, value);
    948     }
    949   }
    950 
    951   private static final long serialVersionUID = 0;
    952 }
    953