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