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