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