1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections.map;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import java.util.AbstractCollection;
24 import java.util.AbstractSet;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.NoSuchElementException;
29 import java.util.Set;
30
31 import org.apache.commons.collections.IterableMap;
32 import org.apache.commons.collections.MapIterator;
33 import org.apache.commons.collections.ResettableIterator;
34 import org.apache.commons.collections.iterators.EmptyIterator;
35 import org.apache.commons.collections.iterators.EmptyMapIterator;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class Flat3Map<K, V> implements IterableMap<K, V>, Serializable, Cloneable {
74
75
76 private static final long serialVersionUID = -6701087419741928296L;
77
78
79 private transient int size;
80
81 private transient int hash1;
82
83 private transient int hash2;
84
85 private transient int hash3;
86
87 private transient K key1;
88
89 private transient K key2;
90
91 private transient K key3;
92
93 private transient V value1;
94
95 private transient V value2;
96
97 private transient V value3;
98
99 private transient AbstractHashedMap<K, V> delegateMap;
100
101
102
103
104 public Flat3Map() {
105 super();
106 }
107
108
109
110
111
112
113
114 public Flat3Map(final Map<? extends K, ? extends V> map) {
115 super();
116 putAll(map);
117 }
118
119
120
121
122
123
124
125
126 public V get(final Object key) {
127 if (delegateMap != null) {
128 return delegateMap.get(key);
129 }
130 if (key == null) {
131 switch (size) {
132
133 case 3:
134 if (key3 == null) {
135 return value3;
136 }
137 case 2:
138 if (key2 == null) {
139 return value2;
140 }
141 case 1:
142 if (key1 == null) {
143 return value1;
144 }
145 }
146 } else {
147 if (size > 0) {
148 final int hashCode = key.hashCode();
149 switch (size) {
150
151 case 3:
152 if (hash3 == hashCode && key.equals(key3)) {
153 return value3;
154 }
155 case 2:
156 if (hash2 == hashCode && key.equals(key2)) {
157 return value2;
158 }
159 case 1:
160 if (hash1 == hashCode && key.equals(key1)) {
161 return value1;
162 }
163 }
164 }
165 }
166 return null;
167 }
168
169
170
171
172
173
174 public int size() {
175 if (delegateMap != null) {
176 return delegateMap.size();
177 }
178 return size;
179 }
180
181
182
183
184
185
186 public boolean isEmpty() {
187 return size() == 0;
188 }
189
190
191
192
193
194
195
196
197 public boolean containsKey(final Object key) {
198 if (delegateMap != null) {
199 return delegateMap.containsKey(key);
200 }
201 if (key == null) {
202 switch (size) {
203 case 3:
204 if (key3 == null) {
205 return true;
206 }
207 case 2:
208 if (key2 == null) {
209 return true;
210 }
211 case 1:
212 if (key1 == null) {
213 return true;
214 }
215 }
216 } else {
217 if (size > 0) {
218 final int hashCode = key.hashCode();
219 switch (size) {
220 case 3:
221 if (hash3 == hashCode && key.equals(key3)) {
222 return true;
223 }
224 case 2:
225 if (hash2 == hashCode && key.equals(key2)) {
226 return true;
227 }
228 case 1:
229 if (hash1 == hashCode && key.equals(key1)) {
230 return true;
231 }
232 }
233 }
234 }
235 return false;
236 }
237
238
239
240
241
242
243
244 public boolean containsValue(final Object value) {
245 if (delegateMap != null) {
246 return delegateMap.containsValue(value);
247 }
248 if (value == null) {
249 switch (size) {
250 case 3:
251 if (value3 == null) {
252 return true;
253 }
254 case 2:
255 if (value2 == null) {
256 return true;
257 }
258 case 1:
259 if (value1 == null) {
260 return true;
261 }
262 }
263 } else {
264 switch (size) {
265 case 3:
266 if (value.equals(value3)) {
267 return true;
268 }
269 case 2:
270 if (value.equals(value2)) {
271 return true;
272 }
273 case 1:
274 if (value.equals(value1)) {
275 return true;
276 }
277 }
278 }
279 return false;
280 }
281
282
283
284
285
286
287
288
289
290 public V put(final K key, final V value) {
291 if (delegateMap != null) {
292 return delegateMap.put(key, value);
293 }
294
295 if (key == null) {
296 switch (size) {
297 case 3:
298 if (key3 == null) {
299 final V old = value3;
300 value3 = value;
301 return old;
302 }
303 case 2:
304 if (key2 == null) {
305 final V old = value2;
306 value2 = value;
307 return old;
308 }
309 case 1:
310 if (key1 == null) {
311 final V old = value1;
312 value1 = value;
313 return old;
314 }
315 }
316 } else {
317 if (size > 0) {
318 final int hashCode = key.hashCode();
319 switch (size) {
320 case 3:
321 if (hash3 == hashCode && key.equals(key3)) {
322 final V old = value3;
323 value3 = value;
324 return old;
325 }
326 case 2:
327 if (hash2 == hashCode && key.equals(key2)) {
328 final V old = value2;
329 value2 = value;
330 return old;
331 }
332 case 1:
333 if (hash1 == hashCode && key.equals(key1)) {
334 final V old = value1;
335 value1 = value;
336 return old;
337 }
338 }
339 }
340 }
341
342
343 switch (size) {
344 default:
345 convertToMap();
346 delegateMap.put(key, value);
347 return null;
348 case 2:
349 hash3 = key == null ? 0 : key.hashCode();
350 key3 = key;
351 value3 = value;
352 break;
353 case 1:
354 hash2 = key == null ? 0 : key.hashCode();
355 key2 = key;
356 value2 = value;
357 break;
358 case 0:
359 hash1 = key == null ? 0 : key.hashCode();
360 key1 = key;
361 value1 = value;
362 break;
363 }
364 size++;
365 return null;
366 }
367
368
369
370
371
372
373
374 public void putAll(final Map<? extends K, ? extends V> map) {
375 final int size = map.size();
376 if (size == 0) {
377 return;
378 }
379 if (delegateMap != null) {
380 delegateMap.putAll(map);
381 return;
382 }
383 if (size < 4) {
384 for (final Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
385 put(entry.getKey(), entry.getValue());
386 }
387 } else {
388 convertToMap();
389 delegateMap.putAll(map);
390 }
391 }
392
393
394
395
396 private void convertToMap() {
397 delegateMap = createDelegateMap();
398 switch (size) {
399 case 3:
400 delegateMap.put(key3, value3);
401 case 2:
402 delegateMap.put(key2, value2);
403 case 1:
404 delegateMap.put(key1, value1);
405 }
406
407 size = 0;
408 hash1 = hash2 = hash3 = 0;
409 key1 = key2 = key3 = null;
410 value1 = value2 = value3 = null;
411 }
412
413
414
415
416
417
418
419
420
421
422
423 protected AbstractHashedMap<K, V> createDelegateMap() {
424 return new HashedMap<K, V>();
425 }
426
427
428
429
430
431
432
433 public V remove(final Object key) {
434 if (delegateMap != null) {
435 return delegateMap.remove(key);
436 }
437 if (size == 0) {
438 return null;
439 }
440 if (key == null) {
441 switch (size) {
442 case 3:
443 if (key3 == null) {
444 final V old = value3;
445 hash3 = 0;
446 key3 = null;
447 value3 = null;
448 size = 2;
449 return old;
450 }
451 if (key2 == null) {
452 final V old = value2;
453 hash2 = hash3;
454 key2 = key3;
455 value2 = value3;
456 hash3 = 0;
457 key3 = null;
458 value3 = null;
459 size = 2;
460 return old;
461 }
462 if (key1 == null) {
463 final V old = value1;
464 hash1 = hash3;
465 key1 = key3;
466 value1 = value3;
467 hash3 = 0;
468 key3 = null;
469 value3 = null;
470 size = 2;
471 return old;
472 }
473 return null;
474 case 2:
475 if (key2 == null) {
476 final V old = value2;
477 hash2 = 0;
478 key2 = null;
479 value2 = null;
480 size = 1;
481 return old;
482 }
483 if (key1 == null) {
484 final V old = value1;
485 hash1 = hash2;
486 key1 = key2;
487 value1 = value2;
488 hash2 = 0;
489 key2 = null;
490 value2 = null;
491 size = 1;
492 return old;
493 }
494 return null;
495 case 1:
496 if (key1 == null) {
497 final V old = value1;
498 hash1 = 0;
499 key1 = null;
500 value1 = null;
501 size = 0;
502 return old;
503 }
504 }
505 } else {
506 if (size > 0) {
507 final int hashCode = key.hashCode();
508 switch (size) {
509 case 3:
510 if (hash3 == hashCode && key.equals(key3)) {
511 final V old = value3;
512 hash3 = 0;
513 key3 = null;
514 value3 = null;
515 size = 2;
516 return old;
517 }
518 if (hash2 == hashCode && key.equals(key2)) {
519 final V old = value2;
520 hash2 = hash3;
521 key2 = key3;
522 value2 = value3;
523 hash3 = 0;
524 key3 = null;
525 value3 = null;
526 size = 2;
527 return old;
528 }
529 if (hash1 == hashCode && key.equals(key1)) {
530 final V old = value1;
531 hash1 = hash3;
532 key1 = key3;
533 value1 = value3;
534 hash3 = 0;
535 key3 = null;
536 value3 = null;
537 size = 2;
538 return old;
539 }
540 return null;
541 case 2:
542 if (hash2 == hashCode && key.equals(key2)) {
543 final V old = value2;
544 hash2 = 0;
545 key2 = null;
546 value2 = null;
547 size = 1;
548 return old;
549 }
550 if (hash1 == hashCode && key.equals(key1)) {
551 final V old = value1;
552 hash1 = hash2;
553 key1 = key2;
554 value1 = value2;
555 hash2 = 0;
556 key2 = null;
557 value2 = null;
558 size = 1;
559 return old;
560 }
561 return null;
562 case 1:
563 if (hash1 == hashCode && key.equals(key1)) {
564 final V old = value1;
565 hash1 = 0;
566 key1 = null;
567 value1 = null;
568 size = 0;
569 return old;
570 }
571 }
572 }
573 }
574 return null;
575 }
576
577
578
579
580
581 public void clear() {
582 if (delegateMap != null) {
583 delegateMap.clear();
584 delegateMap = null;
585 } else {
586 size = 0;
587 hash1 = hash2 = hash3 = 0;
588 key1 = key2 = key3 = null;
589 value1 = value2 = value3 = null;
590 }
591 }
592
593
594
595
596
597
598
599
600
601
602
603
604
605 public MapIterator<K, V> mapIterator() {
606 if (delegateMap != null) {
607 return delegateMap.mapIterator();
608 }
609 if (size == 0) {
610 return EmptyMapIterator.<K, V>emptyMapIterator();
611 }
612 return new FlatMapIterator<K, V>(this);
613 }
614
615
616
617
618 static class FlatMapIterator<K, V> implements MapIterator<K, V>, ResettableIterator<K> {
619 private final Flat3Map<K, V> parent;
620 private int nextIndex = 0;
621 private boolean canRemove = false;
622
623 FlatMapIterator(final Flat3Map<K, V> parent) {
624 super();
625 this.parent = parent;
626 }
627
628 public boolean hasNext() {
629 return nextIndex < parent.size;
630 }
631
632 public K next() {
633 if (hasNext() == false) {
634 throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
635 }
636 canRemove = true;
637 nextIndex++;
638 return getKey();
639 }
640
641 public void remove() {
642 if (canRemove == false) {
643 throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
644 }
645 parent.remove(getKey());
646 nextIndex--;
647 canRemove = false;
648 }
649
650 public K getKey() {
651 if (canRemove == false) {
652 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
653 }
654 switch (nextIndex) {
655 case 3:
656 return parent.key3;
657 case 2:
658 return parent.key2;
659 case 1:
660 return parent.key1;
661 }
662 throw new IllegalStateException("Invalid map index");
663 }
664
665 public V getValue() {
666 if (canRemove == false) {
667 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
668 }
669 switch (nextIndex) {
670 case 3:
671 return parent.value3;
672 case 2:
673 return parent.value2;
674 case 1:
675 return parent.value1;
676 }
677 throw new IllegalStateException("Invalid map index");
678 }
679
680 public V setValue(final V value) {
681 if (canRemove == false) {
682 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
683 }
684 final V old = getValue();
685 switch (nextIndex) {
686 case 3:
687 parent.value3 = value;
688 break;
689 case 2:
690 parent.value2 = value;
691 break;
692 case 1:
693 parent.value1 = value;
694 break;
695 }
696 return old;
697 }
698
699 public void reset() {
700 nextIndex = 0;
701 canRemove = false;
702 }
703
704 @Override
705 public String toString() {
706 if (canRemove) {
707 return "Iterator[" + getKey() + "=" + getValue() + "]";
708 }
709 return "Iterator[]";
710 }
711 }
712
713
714
715
716
717
718
719
720
721
722 public Set<Map.Entry<K, V>> entrySet() {
723 if (delegateMap != null) {
724 return delegateMap.entrySet();
725 }
726 return new EntrySet<K, V>(this);
727 }
728
729
730
731
732 static class EntrySet<K, V> extends AbstractSet<Map.Entry<K, V>> {
733 private final Flat3Map<K, V> parent;
734
735 EntrySet(final Flat3Map<K, V> parent) {
736 super();
737 this.parent = parent;
738 }
739
740 @Override
741 public int size() {
742 return parent.size();
743 }
744
745 @Override
746 public void clear() {
747 parent.clear();
748 }
749
750 @Override
751 public boolean remove(final Object obj) {
752 if (obj instanceof Map.Entry == false) {
753 return false;
754 }
755 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
756 final Object key = entry.getKey();
757 final boolean result = parent.containsKey(key);
758 parent.remove(key);
759 return result;
760 }
761
762 @Override
763 public Iterator<Map.Entry<K, V>> iterator() {
764 if (parent.delegateMap != null) {
765 return parent.delegateMap.entrySet().iterator();
766 }
767 if (parent.size() == 0) {
768 return EmptyIterator.<Map.Entry<K, V>>emptyIterator();
769 }
770 return new EntrySetIterator<K, V>(parent);
771 }
772 }
773
774 static abstract class EntryIterator<K, V> implements Map.Entry<K, V> {
775 private final Flat3Map<K, V> parent;
776 private int nextIndex = 0;
777 protected boolean canRemove = false;
778
779
780
781
782 public EntryIterator(final Flat3Map<K, V> parent) {
783 this.parent = parent;
784 }
785
786 public boolean hasNext() {
787 return nextIndex < parent.size;
788 }
789
790 public Map.Entry<K, V> nextEntry() {
791 if (hasNext() == false) {
792 throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
793 }
794 canRemove = true;
795 nextIndex++;
796 return this;
797 }
798
799 public void remove() {
800 if (canRemove == false) {
801 throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
802 }
803 parent.remove(getKey());
804 nextIndex--;
805 canRemove = false;
806 }
807
808 public K getKey() {
809 if (canRemove == false) {
810 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
811 }
812 switch (nextIndex) {
813 case 3:
814 return parent.key3;
815 case 2:
816 return parent.key2;
817 case 1:
818 return parent.key1;
819 }
820 throw new IllegalStateException("Invalid map index");
821 }
822
823 public V getValue() {
824 if (canRemove == false) {
825 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
826 }
827 switch (nextIndex) {
828 case 3:
829 return parent.value3;
830 case 2:
831 return parent.value2;
832 case 1:
833 return parent.value1;
834 }
835 throw new IllegalStateException("Invalid map index");
836 }
837
838 public V setValue(final V value) {
839 if (canRemove == false) {
840 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
841 }
842 final V old = getValue();
843 switch (nextIndex) {
844 case 3:
845 parent.value3 = value;
846 break;
847 case 2:
848 parent.value2 = value;
849 break;
850 case 1:
851 parent.value1 = value;
852 break;
853 }
854 return old;
855 }
856 }
857
858
859
860
861 static class EntrySetIterator<K, V> extends EntryIterator<K, V> implements Iterator<Map.Entry<K, V>> {
862
863 EntrySetIterator(final Flat3Map<K, V> parent) {
864 super(parent);
865 }
866
867 public Map.Entry<K, V> next() {
868 return nextEntry();
869 }
870
871 @Override
872 public boolean equals(final Object obj) {
873 if (canRemove == false) {
874 return false;
875 }
876 if (obj instanceof Map.Entry == false) {
877 return false;
878 }
879 final Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
880 final Object key = getKey();
881 final Object value = getValue();
882 return (key == null ? other.getKey() == null : key.equals(other.getKey())) &&
883 (value == null ? other.getValue() == null : value.equals(other.getValue()));
884 }
885
886 @Override
887 public int hashCode() {
888 if (canRemove == false) {
889 return 0;
890 }
891 final Object key = getKey();
892 final Object value = getValue();
893 return (key == null ? 0 : key.hashCode()) ^
894 (value == null ? 0 : value.hashCode());
895 }
896
897 @Override
898 public String toString() {
899 if (canRemove) {
900 return getKey() + "=" + getValue();
901 }
902 return "";
903 }
904 }
905
906
907
908
909
910
911
912
913 public Set<K> keySet() {
914 if (delegateMap != null) {
915 return delegateMap.keySet();
916 }
917 return new KeySet<K>(this);
918 }
919
920
921
922
923 static class KeySet<K> extends AbstractSet<K> {
924 private final Flat3Map<K, ?> parent;
925
926 KeySet(final Flat3Map<K, ?> parent) {
927 super();
928 this.parent = parent;
929 }
930
931 @Override
932 public int size() {
933 return parent.size();
934 }
935
936 @Override
937 public void clear() {
938 parent.clear();
939 }
940
941 @Override
942 public boolean contains(final Object key) {
943 return parent.containsKey(key);
944 }
945
946 @Override
947 public boolean remove(final Object key) {
948 final boolean result = parent.containsKey(key);
949 parent.remove(key);
950 return result;
951 }
952
953 @Override
954 public Iterator<K> iterator() {
955 if (parent.delegateMap != null) {
956 return parent.delegateMap.keySet().iterator();
957 }
958 if (parent.size() == 0) {
959 return EmptyIterator.<K>emptyIterator();
960 }
961 return new KeySetIterator<K>(parent);
962 }
963 }
964
965
966
967
968 static class KeySetIterator<K> extends EntryIterator<K, Object> implements Iterator<K>{
969
970 @SuppressWarnings("unchecked")
971 KeySetIterator(final Flat3Map<K, ?> parent) {
972 super((Flat3Map<K, Object>) parent);
973 }
974
975 public K next() {
976 nextEntry();
977 return getKey();
978 }
979 }
980
981
982
983
984
985
986
987
988 public Collection<V> values() {
989 if (delegateMap != null) {
990 return delegateMap.values();
991 }
992 return new Values<V>(this);
993 }
994
995
996
997
998 static class Values<V> extends AbstractCollection<V> {
999 private final Flat3Map<?, V> parent;
1000
1001 Values(final Flat3Map<?, V> parent) {
1002 super();
1003 this.parent = parent;
1004 }
1005
1006 @Override
1007 public int size() {
1008 return parent.size();
1009 }
1010
1011 @Override
1012 public void clear() {
1013 parent.clear();
1014 }
1015
1016 @Override
1017 public boolean contains(final Object value) {
1018 return parent.containsValue(value);
1019 }
1020
1021 @Override
1022 public Iterator<V> iterator() {
1023 if (parent.delegateMap != null) {
1024 return parent.delegateMap.values().iterator();
1025 }
1026 if (parent.size() == 0) {
1027 return EmptyIterator.<V>emptyIterator();
1028 }
1029 return new ValuesIterator<V>(parent);
1030 }
1031 }
1032
1033
1034
1035
1036 static class ValuesIterator<V> extends EntryIterator<Object, V> implements Iterator<V> {
1037
1038 @SuppressWarnings("unchecked")
1039 ValuesIterator(final Flat3Map<?, V> parent) {
1040 super((Flat3Map<Object, V>) parent);
1041 }
1042
1043 public V next() {
1044 nextEntry();
1045 return getValue();
1046 }
1047 }
1048
1049
1050
1051
1052
1053 private void writeObject(final ObjectOutputStream out) throws IOException {
1054 out.defaultWriteObject();
1055 out.writeInt(size());
1056 for (final MapIterator<?, ?> it = mapIterator(); it.hasNext();) {
1057 out.writeObject(it.next());
1058 out.writeObject(it.getValue());
1059 }
1060 }
1061
1062
1063
1064
1065 @SuppressWarnings("unchecked")
1066 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
1067 in.defaultReadObject();
1068 final int count = in.readInt();
1069 if (count > 3) {
1070 delegateMap = createDelegateMap();
1071 }
1072 for (int i = count; i > 0; i--) {
1073 put((K) in.readObject(), (V) in.readObject());
1074 }
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084 @Override
1085 @SuppressWarnings("unchecked")
1086 public Flat3Map<K, V> clone() {
1087 try {
1088 final Flat3Map<K, V> cloned = (Flat3Map<K, V>) super.clone();
1089 if (cloned.delegateMap != null) {
1090 cloned.delegateMap = cloned.delegateMap.clone();
1091 }
1092 return cloned;
1093 } catch (final CloneNotSupportedException ex) {
1094 throw new InternalError();
1095 }
1096 }
1097
1098
1099
1100
1101
1102
1103
1104 @Override
1105 public boolean equals(final Object obj) {
1106 if (obj == this) {
1107 return true;
1108 }
1109 if (delegateMap != null) {
1110 return delegateMap.equals(obj);
1111 }
1112 if (obj instanceof Map == false) {
1113 return false;
1114 }
1115 final Map<?, ?> other = (Map<?, ?>) obj;
1116 if (size != other.size()) {
1117 return false;
1118 }
1119 if (size > 0) {
1120 Object otherValue = null;
1121 switch (size) {
1122 case 3:
1123 if (other.containsKey(key3) == false) {
1124 return false;
1125 }
1126 otherValue = other.get(key3);
1127 if (value3 == null ? otherValue != null : !value3.equals(otherValue)) {
1128 return false;
1129 }
1130 case 2:
1131 if (other.containsKey(key2) == false) {
1132 return false;
1133 }
1134 otherValue = other.get(key2);
1135 if (value2 == null ? otherValue != null : !value2.equals(otherValue)) {
1136 return false;
1137 }
1138 case 1:
1139 if (other.containsKey(key1) == false) {
1140 return false;
1141 }
1142 otherValue = other.get(key1);
1143 if (value1 == null ? otherValue != null : !value1.equals(otherValue)) {
1144 return false;
1145 }
1146 }
1147 }
1148 return true;
1149 }
1150
1151
1152
1153
1154
1155
1156 @Override
1157 public int hashCode() {
1158 if (delegateMap != null) {
1159 return delegateMap.hashCode();
1160 }
1161 int total = 0;
1162 switch (size) {
1163 case 3:
1164 total += hash3 ^ (value3 == null ? 0 : value3.hashCode());
1165 case 2:
1166 total += hash2 ^ (value2 == null ? 0 : value2.hashCode());
1167 case 1:
1168 total += hash1 ^ (value1 == null ? 0 : value1.hashCode());
1169 }
1170 return total;
1171 }
1172
1173
1174
1175
1176
1177
1178 @Override
1179 public String toString() {
1180 if (delegateMap != null) {
1181 return delegateMap.toString();
1182 }
1183 if (size == 0) {
1184 return "{}";
1185 }
1186 final StringBuilder buf = new StringBuilder(128);
1187 buf.append('{');
1188 switch (size) {
1189 case 3:
1190 buf.append(key3 == this ? "(this Map)" : key3);
1191 buf.append('=');
1192 buf.append(value3 == this ? "(this Map)" : value3);
1193 buf.append(',');
1194 case 2:
1195 buf.append(key2 == this ? "(this Map)" : key2);
1196 buf.append('=');
1197 buf.append(value2 == this ? "(this Map)" : value2);
1198 buf.append(',');
1199 case 1:
1200 buf.append(key1 == this ? "(this Map)" : key1);
1201 buf.append('=');
1202 buf.append(value1 == this ? "(this Map)" : value1);
1203 }
1204 buf.append('}');
1205 return buf.toString();
1206 }
1207
1208 }