001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkPositionIndex;
020import static com.google.common.base.Preconditions.checkState;
021import static java.util.Collections.unmodifiableList;
022import static java.util.Objects.requireNonNull;
023
024import com.google.common.annotations.GwtCompatible;
025import com.google.common.annotations.GwtIncompatible;
026import com.google.common.annotations.J2ktIncompatible;
027import com.google.errorprone.annotations.CanIgnoreReturnValue;
028import com.google.j2objc.annotations.WeakOuter;
029import java.io.IOException;
030import java.io.ObjectInputStream;
031import java.io.ObjectOutputStream;
032import java.io.Serializable;
033import java.util.AbstractSequentialList;
034import java.util.Collection;
035import java.util.ConcurrentModificationException;
036import java.util.Iterator;
037import java.util.List;
038import java.util.ListIterator;
039import java.util.Map;
040import java.util.Map.Entry;
041import java.util.NoSuchElementException;
042import java.util.Set;
043import org.jspecify.annotations.Nullable;
044
045/**
046 * An implementation of {@code ListMultimap} that supports deterministic iteration order for both
047 * keys and values. The iteration order is preserved across non-distinct key values. For example,
048 * for the following multimap definition:
049 *
050 * <pre>{@code
051 * Multimap<K, V> multimap = LinkedListMultimap.create();
052 * multimap.put(key1, foo);
053 * multimap.put(key2, bar);
054 * multimap.put(key1, baz);
055 * }</pre>
056 *
057 * ... the iteration order for {@link #keys()} is {@code [key1, key2, key1]}, and similarly for
058 * {@link #entries()}. Unlike {@link LinkedHashMultimap}, the iteration order is kept consistent
059 * between keys, entries and values. For example, calling:
060 *
061 * <pre>{@code
062 * multimap.remove(key1, foo);
063 * }</pre>
064 *
065 * <p>changes the entries iteration order to {@code [key2=bar, key1=baz]} and the key iteration
066 * order to {@code [key2, key1]}. The {@link #entries()} iterator returns mutable map entries, and
067 * {@link #replaceValues} attempts to preserve iteration order as much as possible.
068 *
069 * <p>The collections returned by {@link #keySet()} and {@link #asMap} iterate through the keys in
070 * the order they were first added to the multimap. Similarly, {@link #get}, {@link #removeAll}, and
071 * {@link #replaceValues} return collections that iterate through the values in the order they were
072 * added. The collections generated by {@link #entries()}, {@link #keys()}, and {@link #values}
073 * iterate across the key-value mappings in the order they were added to the multimap.
074 *
075 * <p>The {@link #values()} and {@link #entries()} methods both return a {@code List}, instead of
076 * the {@code Collection} specified by the {@link ListMultimap} interface.
077 *
078 * <p>The methods {@link #get}, {@link #keySet()}, {@link #keys()}, {@link #values}, {@link
079 * #entries()}, and {@link #asMap} return collections that are views of the multimap. If the
080 * multimap is modified while an iteration over any of those collections is in progress, except
081 * through the iterator's methods, the results of the iteration are undefined.
082 *
083 * <p>Keys and values may be null. All optional multimap methods are supported, and all returned
084 * views are modifiable.
085 *
086 * <p>This class is not threadsafe when any concurrent operations update the multimap. Concurrent
087 * read operations will work correctly. To allow concurrent update operations, wrap your multimap
088 * with a call to {@link Multimaps#synchronizedListMultimap}.
089 *
090 * <p>See the Guava User Guide article on <a href=
091 * "https://github.com/google/guava/wiki/NewCollectionTypesExplained#multimap">{@code Multimap}</a>.
092 *
093 * @author Mike Bostock
094 * @since 2.0
095 */
096@GwtCompatible(serializable = true, emulated = true)
097public class LinkedListMultimap<K extends @Nullable Object, V extends @Nullable Object>
098    extends AbstractMultimap<K, V> implements ListMultimap<K, V>, Serializable {
099  /*
100   * Order is maintained using a linked list containing all key-value pairs. In
101   * addition, a series of disjoint linked lists of "siblings", each containing
102   * the values for a specific key, is used to implement {@link
103   * ValueForKeyIterator} in constant time.
104   */
105
106  static final class Node<K extends @Nullable Object, V extends @Nullable Object>
107      extends AbstractMapEntry<K, V> {
108    @ParametricNullness final K key;
109    @ParametricNullness V value;
110    @Nullable Node<K, V> next; // the next node (with any key)
111    @Nullable Node<K, V> previous; // the previous node (with any key)
112    @Nullable Node<K, V> nextSibling; // the next node with the same key
113    @Nullable Node<K, V> previousSibling; // the previous node with the same key
114
115    Node(@ParametricNullness K key, @ParametricNullness V value) {
116      this.key = key;
117      this.value = value;
118    }
119
120    @Override
121    @ParametricNullness
122    public K getKey() {
123      return key;
124    }
125
126    @Override
127    @ParametricNullness
128    public V getValue() {
129      return value;
130    }
131
132    @Override
133    @ParametricNullness
134    public V setValue(@ParametricNullness V newValue) {
135      V result = value;
136      this.value = newValue;
137      return result;
138    }
139  }
140
141  private static class KeyList<K extends @Nullable Object, V extends @Nullable Object> {
142    Node<K, V> head;
143    Node<K, V> tail;
144    int count;
145
146    KeyList(Node<K, V> firstNode) {
147      this.head = firstNode;
148      this.tail = firstNode;
149      firstNode.previousSibling = null;
150      firstNode.nextSibling = null;
151      this.count = 1;
152    }
153  }
154
155  private transient @Nullable Node<K, V> head; // the head for all keys
156  private transient @Nullable Node<K, V> tail; // the tail for all keys
157  private transient Map<K, KeyList<K, V>> keyToKeyList;
158  private transient int size;
159
160  /*
161   * Tracks modifications to keyToKeyList so that addition or removal of keys invalidates
162   * preexisting iterators. This does *not* track simple additions and removals of values
163   * that are not the first to be added or last to be removed for their key.
164   */
165  private transient int modCount;
166
167  /** Creates a new, empty {@code LinkedListMultimap} with the default initial capacity. */
168  public static <K extends @Nullable Object, V extends @Nullable Object>
169      LinkedListMultimap<K, V> create() {
170    return new LinkedListMultimap<>();
171  }
172
173  /**
174   * Constructs an empty {@code LinkedListMultimap} with enough capacity to hold the specified
175   * number of keys without rehashing.
176   *
177   * @param expectedKeys the expected number of distinct keys
178   * @throws IllegalArgumentException if {@code expectedKeys} is negative
179   */
180  public static <K extends @Nullable Object, V extends @Nullable Object>
181      LinkedListMultimap<K, V> create(int expectedKeys) {
182    return new LinkedListMultimap<>(expectedKeys);
183  }
184
185  /**
186   * Constructs a {@code LinkedListMultimap} with the same mappings as the specified {@code
187   * Multimap}. The new multimap has the same {@link Multimap#entries()} iteration order as the
188   * input multimap.
189   *
190   * @param multimap the multimap whose contents are copied to this multimap
191   */
192  public static <K extends @Nullable Object, V extends @Nullable Object>
193      LinkedListMultimap<K, V> create(Multimap<? extends K, ? extends V> multimap) {
194    return new LinkedListMultimap<>(multimap);
195  }
196
197  LinkedListMultimap() {
198    this(12);
199  }
200
201  private LinkedListMultimap(int expectedKeys) {
202    keyToKeyList = Platform.newHashMapWithExpectedSize(expectedKeys);
203  }
204
205  private LinkedListMultimap(Multimap<? extends K, ? extends V> multimap) {
206    this(multimap.keySet().size());
207    putAll(multimap);
208  }
209
210  /**
211   * Adds a new node for the specified key-value pair before the specified {@code nextSibling}
212   * element, or at the end of the list if {@code nextSibling} is null. Note: if {@code nextSibling}
213   * is specified, it MUST be for a node for the same {@code key}!
214   */
215  @CanIgnoreReturnValue
216  private Node<K, V> addNode(
217      @ParametricNullness K key, @ParametricNullness V value, @Nullable Node<K, V> nextSibling) {
218    Node<K, V> node = new Node<>(key, value);
219    if (head == null) { // empty list
220      head = tail = node;
221      keyToKeyList.put(key, new KeyList<K, V>(node));
222      modCount++;
223    } else if (nextSibling == null) { // non-empty list, add to tail
224      // requireNonNull is safe because the list is non-empty.
225      requireNonNull(tail).next = node;
226      node.previous = tail;
227      tail = node;
228      KeyList<K, V> keyList = keyToKeyList.get(key);
229      if (keyList == null) {
230        keyToKeyList.put(key, keyList = new KeyList<>(node));
231        modCount++;
232      } else {
233        keyList.count++;
234        Node<K, V> keyTail = keyList.tail;
235        keyTail.nextSibling = node;
236        node.previousSibling = keyTail;
237        keyList.tail = node;
238      }
239    } else { // non-empty list, insert before nextSibling
240      /*
241       * requireNonNull is safe as long as callers pass a nextSibling that (a) has the same key and
242       * (b) is present in the multimap. (And they do, except maybe in case of concurrent
243       * modification, in which case all bets are off.)
244       */
245      KeyList<K, V> keyList = requireNonNull(keyToKeyList.get(key));
246      keyList.count++;
247      node.previous = nextSibling.previous;
248      node.previousSibling = nextSibling.previousSibling;
249      node.next = nextSibling;
250      node.nextSibling = nextSibling;
251      if (nextSibling.previousSibling == null) { // nextSibling was key head
252        keyList.head = node;
253      } else {
254        nextSibling.previousSibling.nextSibling = node;
255      }
256      if (nextSibling.previous == null) { // nextSibling was head
257        head = node;
258      } else {
259        nextSibling.previous.next = node;
260      }
261      nextSibling.previous = node;
262      nextSibling.previousSibling = node;
263    }
264    size++;
265    return node;
266  }
267
268  /**
269   * Removes the specified node from the linked list. This method is only intended to be used from
270   * the {@code Iterator} classes. See also {@link LinkedListMultimap#removeAllNodes(Object)}.
271   */
272  private void removeNode(Node<K, V> node) {
273    if (node.previous != null) {
274      node.previous.next = node.next;
275    } else { // node was head
276      head = node.next;
277    }
278    if (node.next != null) {
279      node.next.previous = node.previous;
280    } else { // node was tail
281      tail = node.previous;
282    }
283    if (node.previousSibling == null && node.nextSibling == null) {
284      /*
285       * requireNonNull is safe as long as we call removeNode only for nodes that are still in the
286       * Multimap. This should be the case (except in case of concurrent modification, when all bets
287       * are off).
288       */
289      KeyList<K, V> keyList = requireNonNull(keyToKeyList.remove(node.key));
290      keyList.count = 0;
291      modCount++;
292    } else {
293      // requireNonNull is safe (under the conditions listed in the comment in the branch above).
294      KeyList<K, V> keyList = requireNonNull(keyToKeyList.get(node.key));
295      keyList.count--;
296
297      if (node.previousSibling == null) {
298        // requireNonNull is safe because we checked that not *both* siblings were null.
299        keyList.head = requireNonNull(node.nextSibling);
300      } else {
301        node.previousSibling.nextSibling = node.nextSibling;
302      }
303
304      if (node.nextSibling == null) {
305        // requireNonNull is safe because we checked that not *both* siblings were null.
306        keyList.tail = requireNonNull(node.previousSibling);
307      } else {
308        node.nextSibling.previousSibling = node.previousSibling;
309      }
310    }
311    size--;
312  }
313
314  /** Removes all nodes for the specified key. */
315  private void removeAllNodes(@ParametricNullness K key) {
316    Iterators.clear(new ValueForKeyIterator(key));
317  }
318
319  /** An {@code Iterator} over all nodes. */
320  private class NodeIterator implements ListIterator<Entry<K, V>> {
321    int nextIndex;
322    @Nullable Node<K, V> next;
323    @Nullable Node<K, V> current;
324    @Nullable Node<K, V> previous;
325    int expectedModCount = modCount;
326
327    NodeIterator(int index) {
328      int size = size();
329      checkPositionIndex(index, size);
330      if (index >= (size / 2)) {
331        previous = tail;
332        nextIndex = size;
333        while (index++ < size) {
334          previous();
335        }
336      } else {
337        next = head;
338        while (index-- > 0) {
339          next();
340        }
341      }
342      current = null;
343    }
344
345    private void checkForConcurrentModification() {
346      if (modCount != expectedModCount) {
347        throw new ConcurrentModificationException();
348      }
349    }
350
351    @Override
352    public boolean hasNext() {
353      checkForConcurrentModification();
354      return next != null;
355    }
356
357    @CanIgnoreReturnValue
358    @Override
359    public Node<K, V> next() {
360      checkForConcurrentModification();
361      if (next == null) {
362        throw new NoSuchElementException();
363      }
364      previous = current = next;
365      next = next.next;
366      nextIndex++;
367      return current;
368    }
369
370    @Override
371    public void remove() {
372      checkForConcurrentModification();
373      checkState(current != null, "no calls to next() since the last call to remove()");
374      if (current != next) { // after call to next()
375        previous = current.previous;
376        nextIndex--;
377      } else { // after call to previous()
378        next = current.next;
379      }
380      removeNode(current);
381      current = null;
382      expectedModCount = modCount;
383    }
384
385    @Override
386    public boolean hasPrevious() {
387      checkForConcurrentModification();
388      return previous != null;
389    }
390
391    @CanIgnoreReturnValue
392    @Override
393    public Node<K, V> previous() {
394      checkForConcurrentModification();
395      if (previous == null) {
396        throw new NoSuchElementException();
397      }
398      next = current = previous;
399      previous = previous.previous;
400      nextIndex--;
401      return current;
402    }
403
404    @Override
405    public int nextIndex() {
406      return nextIndex;
407    }
408
409    @Override
410    public int previousIndex() {
411      return nextIndex - 1;
412    }
413
414    @Override
415    public void set(Entry<K, V> e) {
416      throw new UnsupportedOperationException();
417    }
418
419    @Override
420    public void add(Entry<K, V> e) {
421      throw new UnsupportedOperationException();
422    }
423
424    void setValue(@ParametricNullness V value) {
425      checkState(current != null);
426      current.value = value;
427    }
428  }
429
430  /** An {@code Iterator} over distinct keys in key head order. */
431  private class DistinctKeyIterator implements Iterator<K> {
432    final Set<K> seenKeys = Sets.<K>newHashSetWithExpectedSize(keySet().size());
433    @Nullable Node<K, V> next = head;
434    @Nullable Node<K, V> current;
435    int expectedModCount = modCount;
436
437    private void checkForConcurrentModification() {
438      if (modCount != expectedModCount) {
439        throw new ConcurrentModificationException();
440      }
441    }
442
443    @Override
444    public boolean hasNext() {
445      checkForConcurrentModification();
446      return next != null;
447    }
448
449    @Override
450    @ParametricNullness
451    public K next() {
452      checkForConcurrentModification();
453      if (next == null) {
454        throw new NoSuchElementException();
455      }
456      current = next;
457      seenKeys.add(current.key);
458      do { // skip ahead to next unseen key
459        next = next.next;
460      } while ((next != null) && !seenKeys.add(next.key));
461      return current.key;
462    }
463
464    @Override
465    public void remove() {
466      checkForConcurrentModification();
467      checkState(current != null, "no calls to next() since the last call to remove()");
468      removeAllNodes(current.key);
469      current = null;
470      expectedModCount = modCount;
471    }
472  }
473
474  /** A {@code ListIterator} over values for a specified key. */
475  private class ValueForKeyIterator implements ListIterator<V> {
476    @ParametricNullness final K key;
477    int nextIndex;
478    @Nullable Node<K, V> next;
479    @Nullable Node<K, V> current;
480    @Nullable Node<K, V> previous;
481
482    /** Constructs a new iterator over all values for the specified key. */
483    ValueForKeyIterator(@ParametricNullness K key) {
484      this.key = key;
485      KeyList<K, V> keyList = keyToKeyList.get(key);
486      next = (keyList == null) ? null : keyList.head;
487    }
488
489    /**
490     * Constructs a new iterator over all values for the specified key starting at the specified
491     * index. This constructor is optimized so that it starts at either the head or the tail,
492     * depending on which is closer to the specified index. This allows adds to the tail to be done
493     * in constant time.
494     *
495     * @throws IndexOutOfBoundsException if index is invalid
496     */
497    public ValueForKeyIterator(@ParametricNullness K key, int index) {
498      KeyList<K, V> keyList = keyToKeyList.get(key);
499      int size = (keyList == null) ? 0 : keyList.count;
500      checkPositionIndex(index, size);
501      if (index >= (size / 2)) {
502        previous = (keyList == null) ? null : keyList.tail;
503        nextIndex = size;
504        while (index++ < size) {
505          previous();
506        }
507      } else {
508        next = (keyList == null) ? null : keyList.head;
509        while (index-- > 0) {
510          next();
511        }
512      }
513      this.key = key;
514      current = null;
515    }
516
517    @Override
518    public boolean hasNext() {
519      return next != null;
520    }
521
522    @CanIgnoreReturnValue
523    @Override
524    @ParametricNullness
525    public V next() {
526      if (next == null) {
527        throw new NoSuchElementException();
528      }
529      previous = current = next;
530      next = next.nextSibling;
531      nextIndex++;
532      return current.value;
533    }
534
535    @Override
536    public boolean hasPrevious() {
537      return previous != null;
538    }
539
540    @CanIgnoreReturnValue
541    @Override
542    @ParametricNullness
543    public V previous() {
544      if (previous == null) {
545        throw new NoSuchElementException();
546      }
547      next = current = previous;
548      previous = previous.previousSibling;
549      nextIndex--;
550      return current.value;
551    }
552
553    @Override
554    public int nextIndex() {
555      return nextIndex;
556    }
557
558    @Override
559    public int previousIndex() {
560      return nextIndex - 1;
561    }
562
563    @Override
564    public void remove() {
565      checkState(current != null, "no calls to next() since the last call to remove()");
566      if (current != next) { // after call to next()
567        previous = current.previousSibling;
568        nextIndex--;
569      } else { // after call to previous()
570        next = current.nextSibling;
571      }
572      removeNode(current);
573      current = null;
574    }
575
576    @Override
577    public void set(@ParametricNullness V value) {
578      checkState(current != null);
579      current.value = value;
580    }
581
582    @Override
583    public void add(@ParametricNullness V value) {
584      previous = addNode(key, value, next);
585      nextIndex++;
586      current = null;
587    }
588  }
589
590  // Query Operations
591
592  @Override
593  public int size() {
594    return size;
595  }
596
597  @Override
598  public boolean isEmpty() {
599    return head == null;
600  }
601
602  @Override
603  public boolean containsKey(@Nullable Object key) {
604    return keyToKeyList.containsKey(key);
605  }
606
607  @Override
608  public boolean containsValue(@Nullable Object value) {
609    return values().contains(value);
610  }
611
612  // Modification Operations
613
614  /**
615   * Stores a key-value pair in the multimap.
616   *
617   * @param key key to store in the multimap
618   * @param value value to store in the multimap
619   * @return {@code true} always
620   */
621  @CanIgnoreReturnValue
622  @Override
623  public boolean put(@ParametricNullness K key, @ParametricNullness V value) {
624    addNode(key, value, null);
625    return true;
626  }
627
628  // Bulk Operations
629
630  /**
631   * {@inheritDoc}
632   *
633   * <p>If any entries for the specified {@code key} already exist in the multimap, their values are
634   * changed in-place without affecting the iteration order.
635   *
636   * <p>The returned list is immutable and implements {@link java.util.RandomAccess}.
637   */
638  @CanIgnoreReturnValue
639  @Override
640  public List<V> replaceValues(@ParametricNullness K key, Iterable<? extends V> values) {
641    List<V> oldValues = getCopy(key);
642    ListIterator<V> keyValues = new ValueForKeyIterator(key);
643    Iterator<? extends V> newValues = values.iterator();
644
645    // Replace existing values, if any.
646    while (keyValues.hasNext() && newValues.hasNext()) {
647      keyValues.next();
648      keyValues.set(newValues.next());
649    }
650
651    // Remove remaining old values, if any.
652    while (keyValues.hasNext()) {
653      keyValues.next();
654      keyValues.remove();
655    }
656
657    // Add remaining new values, if any.
658    while (newValues.hasNext()) {
659      keyValues.add(newValues.next());
660    }
661
662    return oldValues;
663  }
664
665  private List<V> getCopy(@ParametricNullness K key) {
666    return unmodifiableList(Lists.newArrayList(new ValueForKeyIterator(key)));
667  }
668
669  /**
670   * {@inheritDoc}
671   *
672   * <p>The returned list is immutable and implements {@link java.util.RandomAccess}.
673   */
674  @CanIgnoreReturnValue
675  @Override
676  public List<V> removeAll(@Nullable Object key) {
677    /*
678     * Safe because all we do is remove values for the key, not add them. (If we wanted to make sure
679     * to call getCopy and removeAllNodes only with a true K, then we could check containsKey first.
680     * But that check wouldn't eliminate the warnings.)
681     */
682    @SuppressWarnings({"unchecked", "nullness"})
683    K castKey = (K) key;
684    List<V> oldValues = getCopy(castKey);
685    removeAllNodes(castKey);
686    return oldValues;
687  }
688
689  @Override
690  public void clear() {
691    head = null;
692    tail = null;
693    keyToKeyList.clear();
694    size = 0;
695    modCount++;
696  }
697
698  // Views
699
700  /**
701   * {@inheritDoc}
702   *
703   * <p>If the multimap is modified while an iteration over the list is in progress (except through
704   * the iterator's own {@code add}, {@code set} or {@code remove} operations) the results of the
705   * iteration are undefined.
706   *
707   * <p>The returned list is not serializable and does not have random access.
708   */
709  @Override
710  public List<V> get(@ParametricNullness final K key) {
711    return new AbstractSequentialList<V>() {
712      @Override
713      public int size() {
714        KeyList<K, V> keyList = keyToKeyList.get(key);
715        return (keyList == null) ? 0 : keyList.count;
716      }
717
718      @Override
719      public ListIterator<V> listIterator(int index) {
720        return new ValueForKeyIterator(key, index);
721      }
722    };
723  }
724
725  @Override
726  Set<K> createKeySet() {
727    @WeakOuter
728    class KeySetImpl extends Sets.ImprovedAbstractSet<K> {
729      @Override
730      public int size() {
731        return keyToKeyList.size();
732      }
733
734      @Override
735      public Iterator<K> iterator() {
736        return new DistinctKeyIterator();
737      }
738
739      @Override
740      public boolean contains(@Nullable Object key) { // for performance
741        return containsKey(key);
742      }
743
744      @Override
745      public boolean remove(@Nullable Object o) { // for performance
746        return !LinkedListMultimap.this.removeAll(o).isEmpty();
747      }
748    }
749    return new KeySetImpl();
750  }
751
752  @Override
753  Multiset<K> createKeys() {
754    return new Multimaps.Keys<K, V>(this);
755  }
756
757  /**
758   * {@inheritDoc}
759   *
760   * <p>The iterator generated by the returned collection traverses the values in the order they
761   * were added to the multimap. Because the values may have duplicates and follow the insertion
762   * ordering, this method returns a {@link List}, instead of the {@link Collection} specified in
763   * the {@link ListMultimap} interface.
764   */
765  @Override
766  public List<V> values() {
767    return (List<V>) super.values();
768  }
769
770  @Override
771  List<V> createValues() {
772    @WeakOuter
773    class ValuesImpl extends AbstractSequentialList<V> {
774      @Override
775      public int size() {
776        return size;
777      }
778
779      @Override
780      public ListIterator<V> listIterator(int index) {
781        final NodeIterator nodeItr = new NodeIterator(index);
782        return new TransformedListIterator<Entry<K, V>, V>(nodeItr) {
783          @Override
784          @ParametricNullness
785          V transform(Entry<K, V> entry) {
786            return entry.getValue();
787          }
788
789          @Override
790          public void set(@ParametricNullness V value) {
791            nodeItr.setValue(value);
792          }
793        };
794      }
795    }
796    return new ValuesImpl();
797  }
798
799  /**
800   * {@inheritDoc}
801   *
802   * <p>The iterator generated by the returned collection traverses the entries in the order they
803   * were added to the multimap. Because the entries may have duplicates and follow the insertion
804   * ordering, this method returns a {@link List}, instead of the {@link Collection} specified in
805   * the {@link ListMultimap} interface.
806   *
807   * <p>An entry's {@link Entry#getKey} method always returns the same key, regardless of what
808   * happens subsequently. As long as the corresponding key-value mapping is not removed from the
809   * multimap, {@link Entry#getValue} returns the value from the multimap, which may change over
810   * time, and {@link Entry#setValue} modifies that value. Removing the mapping from the multimap
811   * does not alter the value returned by {@code getValue()}, though a subsequent {@code setValue()}
812   * call won't update the multimap but will lead to a revised value being returned by {@code
813   * getValue()}.
814   */
815  @Override
816  public List<Entry<K, V>> entries() {
817    return (List<Entry<K, V>>) super.entries();
818  }
819
820  @Override
821  List<Entry<K, V>> createEntries() {
822    @WeakOuter
823    class EntriesImpl extends AbstractSequentialList<Entry<K, V>> {
824      @Override
825      public int size() {
826        return size;
827      }
828
829      @Override
830      public ListIterator<Entry<K, V>> listIterator(int index) {
831        return new NodeIterator(index);
832      }
833    }
834    return new EntriesImpl();
835  }
836
837  @Override
838  Iterator<Entry<K, V>> entryIterator() {
839    throw new AssertionError("should never be called");
840  }
841
842  @Override
843  Map<K, Collection<V>> createAsMap() {
844    return new Multimaps.AsMap<>(this);
845  }
846
847  /**
848   * @serialData the number of distinct keys, and then for each distinct key: the first key, the
849   *     number of values for that key, and the key's values, followed by successive keys and values
850   *     from the entries() ordering
851   */
852  @GwtIncompatible // java.io.ObjectOutputStream
853  @J2ktIncompatible
854  private void writeObject(ObjectOutputStream stream) throws IOException {
855    stream.defaultWriteObject();
856    stream.writeInt(size());
857    for (Entry<K, V> entry : entries()) {
858      stream.writeObject(entry.getKey());
859      stream.writeObject(entry.getValue());
860    }
861  }
862
863  @GwtIncompatible // java.io.ObjectInputStream
864  @J2ktIncompatible
865  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
866    stream.defaultReadObject();
867    keyToKeyList = CompactLinkedHashMap.create();
868    int size = stream.readInt();
869    for (int i = 0; i < size; i++) {
870      @SuppressWarnings("unchecked") // reading data stored by writeObject
871      K key = (K) stream.readObject();
872      @SuppressWarnings("unchecked") // reading data stored by writeObject
873      V value = (V) stream.readObject();
874      put(key, value);
875    }
876  }
877
878  @GwtIncompatible // java serialization not supported
879  @J2ktIncompatible
880  private static final long serialVersionUID = 0;
881}