1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections.bidimap;
18
19 import java.util.AbstractSet;
20 import java.util.Collection;
21 import java.util.ConcurrentModificationException;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.NoSuchElementException;
25 import java.util.Set;
26
27 import org.apache.commons.collections.KeyValue;
28 import org.apache.commons.collections.MapIterator;
29 import org.apache.commons.collections.OrderedBidiMap;
30 import org.apache.commons.collections.OrderedIterator;
31 import org.apache.commons.collections.OrderedMapIterator;
32 import org.apache.commons.collections.iterators.EmptyOrderedMapIterator;
33 import org.apache.commons.collections.keyvalue.UnmodifiableMapEntry;
34
35 import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.KEY;
36 import static org.apache.commons.collections.bidimap.TreeBidiMap.DataElement.VALUE;
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
74
75 public class TreeBidiMap<K extends Comparable<K>, V extends Comparable<V>> implements OrderedBidiMap<K, V> {
76
77 static enum DataElement {
78 KEY("key"), VALUE("value");
79
80 private final String description;
81
82
83
84
85
86
87 private DataElement(final String description) {
88 this.description = description;
89 }
90
91 @Override
92 public String toString() {
93 return description;
94 }
95 }
96
97 private Node<K, V>[] rootNode;
98 private int nodeCount = 0;
99 private int modifications = 0;
100 private Set<K> keySet;
101 private Set<V> valuesSet;
102 private Set<Map.Entry<K, V>> entrySet;
103 private Inverse inverse = null;
104
105
106
107
108
109 @SuppressWarnings("unchecked")
110 public TreeBidiMap() {
111 super();
112 rootNode = new Node[2];
113 }
114
115
116
117
118
119
120
121
122
123 public TreeBidiMap(final Map<K, V> map) {
124 this();
125 putAll(map);
126 }
127
128
129
130
131
132
133
134 public int size() {
135 return nodeCount;
136 }
137
138
139
140
141
142
143 public boolean isEmpty() {
144 return nodeCount == 0;
145 }
146
147
148
149
150
151
152
153
154
155
156
157 public boolean containsKey(final Object key) {
158 checkKey(key);
159 return lookupKey(key) != null;
160 }
161
162
163
164
165
166
167
168
169
170
171
172 public boolean containsValue(final Object value) {
173 checkValue(value);
174 return lookupValue(value) != null;
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189 public V get(final Object key) {
190 checkKey(key);
191 final Node<K, V> node = lookupKey(key);
192 return node == null ? null : node.getValue();
193 }
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 public V put(final K key, final V value) {
220 final V result = get(key);
221 doPut(key, value);
222 return result;
223 }
224
225
226
227
228
229
230
231
232 public void putAll(final Map<? extends K, ? extends V> map) {
233 for (final Map.Entry<? extends K, ? extends V> e : map.entrySet()) {
234 put(e.getKey(), e.getValue());
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249 public V remove(final Object key) {
250 return doRemoveKey(key);
251 }
252
253
254
255
256 public void clear() {
257 modify();
258
259 nodeCount = 0;
260 rootNode[KEY.ordinal()] = null;
261 rootNode[VALUE.ordinal()] = null;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 public K getKey(final Object value) {
278 checkValue(value);
279 final Node<K, V> node = lookupValue(value);
280 return node == null ? null : node.getKey();
281 }
282
283
284
285
286
287
288
289
290
291
292
293
294 public K removeValue(final Object value) {
295 return doRemoveValue(value);
296 }
297
298
299
300
301
302
303
304
305 public K firstKey() {
306 if (nodeCount == 0) {
307 throw new NoSuchElementException("Map is empty");
308 }
309 return leastNode(rootNode[KEY.ordinal()], KEY).getKey();
310 }
311
312
313
314
315
316
317
318 public K lastKey() {
319 if (nodeCount == 0) {
320 throw new NoSuchElementException("Map is empty");
321 }
322 return greatestNode(rootNode[KEY.ordinal()], KEY).getKey();
323 }
324
325
326
327
328
329
330
331
332
333 public K nextKey(final K key) {
334 checkKey(key);
335 final Node<K, V> node = nextGreater(lookupKey(key), KEY);
336 return node == null ? null : node.getKey();
337 }
338
339
340
341
342
343
344
345
346
347 public K previousKey(final K key) {
348 checkKey(key);
349 final Node<K, V> node = nextSmaller(lookupKey(key), KEY);
350 return node == null ? null : node.getKey();
351 }
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 public Set<K> keySet() {
367 if (keySet == null) {
368 keySet = new KeyView(KEY);
369 }
370 return keySet;
371 }
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 public Collection<V> values() {
388 if (valuesSet == null) {
389 valuesSet = new ValueView(KEY);
390 }
391 return valuesSet;
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409 public Set<Map.Entry<K, V>> entrySet() {
410 if (entrySet == null) {
411 entrySet = new EntryView();
412 }
413 return entrySet;
414 }
415
416
417 public OrderedMapIterator<K, V> mapIterator() {
418 if (isEmpty()) {
419 return EmptyOrderedMapIterator.<K, V>emptyOrderedMapIterator();
420 }
421 return new ViewMapIterator(KEY);
422 }
423
424
425
426
427
428
429
430 public OrderedBidiMap<V, K> inverseBidiMap() {
431 if (inverse == null) {
432 inverse = new Inverse();
433 }
434 return inverse;
435 }
436
437
438
439
440
441
442
443
444 @Override
445 public boolean equals(final Object obj) {
446 return this.doEquals(obj, KEY);
447 }
448
449
450
451
452
453
454 @Override
455 public int hashCode() {
456 return this.doHashCode(KEY);
457 }
458
459
460
461
462
463
464 @Override
465 public String toString() {
466 return this.doToString(KEY);
467 }
468
469
470
471
472
473
474
475
476 private void doPut(final K key, final V value) {
477 checkKeyAndValue(key, value);
478
479
480 doRemoveKey(key);
481 doRemoveValue(value);
482
483 Node<K, V> node = rootNode[KEY.ordinal()];
484 if (node == null) {
485
486 final Node<K, V> root = new Node<K, V>(key, value);
487 rootNode[KEY.ordinal()] = root;
488 rootNode[VALUE.ordinal()] = root;
489 grow();
490
491 } else {
492
493 while (true) {
494 final int cmp = compare(key, node.getKey());
495
496 if (cmp == 0) {
497
498 throw new IllegalArgumentException("Cannot store a duplicate key (\"" + key + "\") in this Map");
499 } else if (cmp < 0) {
500 if (node.getLeft(KEY) != null) {
501 node = node.getLeft(KEY);
502 } else {
503 final Node<K, V> newNode = new Node<K, V>(key, value);
504
505 insertValue(newNode);
506 node.setLeft(newNode, KEY);
507 newNode.setParent(node, KEY);
508 doRedBlackInsert(newNode, KEY);
509 grow();
510
511 break;
512 }
513 } else {
514 if (node.getRight(KEY) != null) {
515 node = node.getRight(KEY);
516 } else {
517 final Node<K, V> newNode = new Node<K, V>(key, value);
518
519 insertValue(newNode);
520 node.setRight(newNode, KEY);
521 newNode.setParent(node, KEY);
522 doRedBlackInsert(newNode, KEY);
523 grow();
524
525 break;
526 }
527 }
528 }
529 }
530 }
531
532 private V doRemoveKey(final Object key) {
533 final Node<K, V> node = lookupKey(key);
534 if (node == null) {
535 return null;
536 }
537 doRedBlackDelete(node);
538 return node.getValue();
539 }
540
541 private K doRemoveValue(final Object value) {
542 final Node<K, V> node = lookupValue(value);
543 if (node == null) {
544 return null;
545 }
546 doRedBlackDelete(node);
547 return node.getKey();
548 }
549
550
551
552
553
554
555
556
557
558 @SuppressWarnings("unchecked")
559 private <T extends Comparable<T>> Node<K, V> lookup(final Object data, final DataElement dataElement) {
560 Node<K, V> rval = null;
561 Node<K, V> node = rootNode[dataElement.ordinal()];
562
563 while (node != null) {
564 final int cmp = compare((T) data, (T) node.getData(dataElement));
565 if (cmp == 0) {
566 rval = node;
567 break;
568 } else {
569 node = cmp < 0 ? node.getLeft(dataElement) : node.getRight(dataElement);
570 }
571 }
572
573 return rval;
574 }
575
576 private Node<K, V> lookupKey(final Object key) {
577 return this.<K>lookup(key, KEY);
578 }
579
580 private Node<K, V> lookupValue(final Object value) {
581 return this.<V>lookup(value, VALUE);
582 }
583
584
585
586
587
588
589
590
591 private Node<K, V> nextGreater(final Node<K, V> node, final DataElement dataElement) {
592 Node<K, V> rval;
593 if (node == null) {
594 rval = null;
595 } else if (node.getRight(dataElement) != null) {
596
597
598 rval = leastNode(node.getRight(dataElement), dataElement);
599 } else {
600
601
602
603
604
605
606 Node<K, V> parent = node.getParent(dataElement);
607 Node<K, V> child = node;
608
609 while (parent != null && child == parent.getRight(dataElement)) {
610 child = parent;
611 parent = parent.getParent(dataElement);
612 }
613 rval = parent;
614 }
615 return rval;
616 }
617
618
619
620
621
622
623
624
625 private Node<K, V> nextSmaller(final Node<K, V> node, final DataElement dataElement) {
626 Node<K, V> rval;
627 if (node == null) {
628 rval = null;
629 } else if (node.getLeft(dataElement) != null) {
630
631
632 rval = greatestNode(node.getLeft(dataElement), dataElement);
633 } else {
634
635
636
637
638
639
640 Node<K, V> parent = node.getParent(dataElement);
641 Node<K, V> child = node;
642
643 while (parent != null && child == parent.getLeft(dataElement)) {
644 child = parent;
645 parent = parent.getParent(dataElement);
646 }
647 rval = parent;
648 }
649 return rval;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663 private static <T extends Comparable<T>> int compare(final T o1, final T o2) {
664 return o1.compareTo(o2);
665 }
666
667
668
669
670
671
672
673
674
675 private Node<K, V> leastNode(final Node<K, V> node, final DataElement dataElement) {
676 Node<K, V> rval = node;
677 if (rval != null) {
678 while (rval.getLeft(dataElement) != null) {
679 rval = rval.getLeft(dataElement);
680 }
681 }
682 return rval;
683 }
684
685
686
687
688
689
690
691
692 private Node<K, V> greatestNode(final Node<K, V> node, final DataElement dataElement) {
693 Node<K, V> rval = node;
694 if (rval != null) {
695 while (rval.getRight(dataElement) != null) {
696 rval = rval.getRight(dataElement);
697 }
698 }
699 return rval;
700 }
701
702
703
704
705
706
707
708
709
710 private void copyColor(final Node<K, V> from, final Node<K, V> to, final DataElement dataElement) {
711 if (to != null) {
712 if (from == null) {
713
714 to.setBlack(dataElement);
715 } else {
716 to.copyColor(from, dataElement);
717 }
718 }
719 }
720
721
722
723
724
725
726
727
728 private static boolean isRed(final Node<?, ?> node, final DataElement dataElement) {
729 return node != null && node.isRed(dataElement);
730 }
731
732
733
734
735
736
737
738
739 private static boolean isBlack(final Node<?, ?> node, final DataElement dataElement) {
740 return node == null || node.isBlack(dataElement);
741 }
742
743
744
745
746
747
748
749 private static void makeRed(final Node<?, ?> node, final DataElement dataElement) {
750 if (node != null) {
751 node.setRed(dataElement);
752 }
753 }
754
755
756
757
758
759
760
761 private static void makeBlack(final Node<?, ?> node, final DataElement dataElement) {
762 if (node != null) {
763 node.setBlack(dataElement);
764 }
765 }
766
767
768
769
770
771
772
773
774 private Node<K, V> getGrandParent(final Node<K, V> node, final DataElement dataElement) {
775 return getParent(getParent(node, dataElement), dataElement);
776 }
777
778
779
780
781
782
783
784
785 private Node<K, V> getParent(final Node<K, V> node, final DataElement dataElement) {
786 return node == null ? null : node.getParent(dataElement);
787 }
788
789
790
791
792
793
794
795
796 private Node<K, V> getRightChild(final Node<K, V> node, final DataElement dataElement) {
797 return node == null ? null : node.getRight(dataElement);
798 }
799
800
801
802
803
804
805
806
807 private Node<K, V> getLeftChild(final Node<K, V> node, final DataElement dataElement) {
808 return node == null ? null : node.getLeft(dataElement);
809 }
810
811
812
813
814
815
816
817 private void rotateLeft(final Node<K, V> node, final DataElement dataElement) {
818 final Node<K, V> rightChild = node.getRight(dataElement);
819 node.setRight(rightChild.getLeft(dataElement), dataElement);
820
821 if (rightChild.getLeft(dataElement) != null) {
822 rightChild.getLeft(dataElement).setParent(node, dataElement);
823 }
824 rightChild.setParent(node.getParent(dataElement), dataElement);
825
826 if (node.getParent(dataElement) == null) {
827
828 rootNode[dataElement.ordinal()] = rightChild;
829 } else if (node.getParent(dataElement).getLeft(dataElement) == node) {
830 node.getParent(dataElement).setLeft(rightChild, dataElement);
831 } else {
832 node.getParent(dataElement).setRight(rightChild, dataElement);
833 }
834
835 rightChild.setLeft(node, dataElement);
836 node.setParent(rightChild, dataElement);
837 }
838
839
840
841
842
843
844
845 private void rotateRight(final Node<K, V> node, final DataElement dataElement) {
846 final Node<K, V> leftChild = node.getLeft(dataElement);
847 node.setLeft(leftChild.getRight(dataElement), dataElement);
848 if (leftChild.getRight(dataElement) != null) {
849 leftChild.getRight(dataElement).setParent(node, dataElement);
850 }
851 leftChild.setParent(node.getParent(dataElement), dataElement);
852
853 if (node.getParent(dataElement) == null) {
854
855 rootNode[dataElement.ordinal()] = leftChild;
856 } else if (node.getParent(dataElement).getRight(dataElement) == node) {
857 node.getParent(dataElement).setRight(leftChild, dataElement);
858 } else {
859 node.getParent(dataElement).setLeft(leftChild, dataElement);
860 }
861
862 leftChild.setRight(node, dataElement);
863 node.setParent(leftChild, dataElement);
864 }
865
866
867
868
869
870
871
872
873 private void doRedBlackInsert(final Node<K, V> insertedNode, final DataElement dataElement) {
874 Node<K, V> currentNode = insertedNode;
875 makeRed(currentNode, dataElement);
876
877 while (currentNode != null
878 && currentNode != rootNode[dataElement.ordinal()]
879 && isRed(currentNode.getParent(dataElement), dataElement)) {
880 if (currentNode.isLeftChild(dataElement)) {
881 final Node<K, V> y = getRightChild(getGrandParent(currentNode, dataElement), dataElement);
882
883 if (isRed(y, dataElement)) {
884 makeBlack(getParent(currentNode, dataElement), dataElement);
885 makeBlack(y, dataElement);
886 makeRed(getGrandParent(currentNode, dataElement), dataElement);
887
888 currentNode = getGrandParent(currentNode, dataElement);
889 } else {
890
891 if (currentNode.isRightChild(dataElement)) {
892 currentNode = getParent(currentNode, dataElement);
893
894 rotateLeft(currentNode, dataElement);
895 }
896
897 makeBlack(getParent(currentNode, dataElement), dataElement);
898 makeRed(getGrandParent(currentNode, dataElement), dataElement);
899
900 if (getGrandParent(currentNode, dataElement) != null) {
901 rotateRight(getGrandParent(currentNode, dataElement), dataElement);
902 }
903 }
904 } else {
905
906
907 final Node<K, V> y = getLeftChild(getGrandParent(currentNode, dataElement), dataElement);
908
909 if (isRed(y, dataElement)) {
910 makeBlack(getParent(currentNode, dataElement), dataElement);
911 makeBlack(y, dataElement);
912 makeRed(getGrandParent(currentNode, dataElement), dataElement);
913
914 currentNode = getGrandParent(currentNode, dataElement);
915 } else {
916
917 if (currentNode.isLeftChild(dataElement)) {
918 currentNode = getParent(currentNode, dataElement);
919
920 rotateRight(currentNode, dataElement);
921 }
922
923 makeBlack(getParent(currentNode, dataElement), dataElement);
924 makeRed(getGrandParent(currentNode, dataElement), dataElement);
925
926 if (getGrandParent(currentNode, dataElement) != null) {
927 rotateLeft(getGrandParent(currentNode, dataElement), dataElement);
928 }
929 }
930 }
931 }
932
933 makeBlack(rootNode[dataElement.ordinal()], dataElement);
934 }
935
936
937
938
939
940
941
942 private void doRedBlackDelete(final Node<K, V> deletedNode) {
943 for (final DataElement dataElement : DataElement.values()) {
944
945
946 if (deletedNode.getLeft(dataElement) != null && deletedNode.getRight(dataElement) != null) {
947 swapPosition(nextGreater(deletedNode, dataElement), deletedNode, dataElement);
948 }
949
950 final Node<K, V> replacement = deletedNode.getLeft(dataElement) != null ?
951 deletedNode.getLeft(dataElement) : deletedNode.getRight(dataElement);
952
953 if (replacement != null) {
954 replacement.setParent(deletedNode.getParent(dataElement), dataElement);
955
956 if (deletedNode.getParent(dataElement) == null) {
957 rootNode[dataElement.ordinal()] = replacement;
958 } else if (deletedNode == deletedNode.getParent(dataElement).getLeft(dataElement)) {
959 deletedNode.getParent(dataElement).setLeft(replacement, dataElement);
960 } else {
961 deletedNode.getParent(dataElement).setRight(replacement, dataElement);
962 }
963
964 deletedNode.setLeft(null, dataElement);
965 deletedNode.setRight(null, dataElement);
966 deletedNode.setParent(null, dataElement);
967
968 if (isBlack(deletedNode, dataElement)) {
969 doRedBlackDeleteFixup(replacement, dataElement);
970 }
971 } else {
972
973
974 if (deletedNode.getParent(dataElement) == null) {
975
976
977 rootNode[dataElement.ordinal()] = null;
978 } else {
979
980
981 if (isBlack(deletedNode, dataElement)) {
982 doRedBlackDeleteFixup(deletedNode, dataElement);
983 }
984
985 if (deletedNode.getParent(dataElement) != null) {
986 if (deletedNode == deletedNode.getParent(dataElement).getLeft(dataElement)) {
987 deletedNode.getParent(dataElement).setLeft(null, dataElement);
988 } else {
989 deletedNode.getParent(dataElement).setRight(null, dataElement);
990 }
991
992 deletedNode.setParent(null, dataElement);
993 }
994 }
995 }
996 }
997 shrink();
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009 private void doRedBlackDeleteFixup(final Node<K, V> replacementNode, final DataElement dataElement) {
1010 Node<K, V> currentNode = replacementNode;
1011
1012 while (currentNode != rootNode[dataElement.ordinal()] && isBlack(currentNode, dataElement)) {
1013 if (currentNode.isLeftChild(dataElement)) {
1014 Node<K, V> siblingNode = getRightChild(getParent(currentNode, dataElement), dataElement);
1015
1016 if (isRed(siblingNode, dataElement)) {
1017 makeBlack(siblingNode, dataElement);
1018 makeRed(getParent(currentNode, dataElement), dataElement);
1019 rotateLeft(getParent(currentNode, dataElement), dataElement);
1020
1021 siblingNode = getRightChild(getParent(currentNode, dataElement), dataElement);
1022 }
1023
1024 if (isBlack(getLeftChild(siblingNode, dataElement), dataElement)
1025 && isBlack(getRightChild(siblingNode, dataElement), dataElement)) {
1026 makeRed(siblingNode, dataElement);
1027
1028 currentNode = getParent(currentNode, dataElement);
1029 } else {
1030 if (isBlack(getRightChild(siblingNode, dataElement), dataElement)) {
1031 makeBlack(getLeftChild(siblingNode, dataElement), dataElement);
1032 makeRed(siblingNode, dataElement);
1033 rotateRight(siblingNode, dataElement);
1034
1035 siblingNode = getRightChild(getParent(currentNode, dataElement), dataElement);
1036 }
1037
1038 copyColor(getParent(currentNode, dataElement), siblingNode, dataElement);
1039 makeBlack(getParent(currentNode, dataElement), dataElement);
1040 makeBlack(getRightChild(siblingNode, dataElement), dataElement);
1041 rotateLeft(getParent(currentNode, dataElement), dataElement);
1042
1043 currentNode = rootNode[dataElement.ordinal()];
1044 }
1045 } else {
1046 Node<K, V> siblingNode = getLeftChild(getParent(currentNode, dataElement), dataElement);
1047
1048 if (isRed(siblingNode, dataElement)) {
1049 makeBlack(siblingNode, dataElement);
1050 makeRed(getParent(currentNode, dataElement), dataElement);
1051 rotateRight(getParent(currentNode, dataElement), dataElement);
1052
1053 siblingNode = getLeftChild(getParent(currentNode, dataElement), dataElement);
1054 }
1055
1056 if (isBlack(getRightChild(siblingNode, dataElement), dataElement)
1057 && isBlack(getLeftChild(siblingNode, dataElement), dataElement)) {
1058 makeRed(siblingNode, dataElement);
1059
1060 currentNode = getParent(currentNode, dataElement);
1061 } else {
1062 if (isBlack(getLeftChild(siblingNode, dataElement), dataElement)) {
1063 makeBlack(getRightChild(siblingNode, dataElement), dataElement);
1064 makeRed(siblingNode, dataElement);
1065 rotateLeft(siblingNode, dataElement);
1066
1067 siblingNode = getLeftChild(getParent(currentNode, dataElement), dataElement);
1068 }
1069
1070 copyColor(getParent(currentNode, dataElement), siblingNode, dataElement);
1071 makeBlack(getParent(currentNode, dataElement), dataElement);
1072 makeBlack(getLeftChild(siblingNode, dataElement), dataElement);
1073 rotateRight(getParent(currentNode, dataElement), dataElement);
1074
1075 currentNode = rootNode[dataElement.ordinal()];
1076 }
1077 }
1078 }
1079
1080 makeBlack(currentNode, dataElement);
1081 }
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 private void swapPosition(final Node<K, V> x, final Node<K, V> y, final DataElement dataElement) {
1093
1094 final Node<K, V> xFormerParent = x.getParent(dataElement);
1095 final Node<K, V> xFormerLeftChild = x.getLeft(dataElement);
1096 final Node<K, V> xFormerRightChild = x.getRight(dataElement);
1097 final Node<K, V> yFormerParent = y.getParent(dataElement);
1098 final Node<K, V> yFormerLeftChild = y.getLeft(dataElement);
1099 final Node<K, V> yFormerRightChild = y.getRight(dataElement);
1100 final boolean xWasLeftChild =
1101 x.getParent(dataElement) != null && x == x.getParent(dataElement).getLeft(dataElement);
1102 final boolean yWasLeftChild =
1103 y.getParent(dataElement) != null && y == y.getParent(dataElement).getLeft(dataElement);
1104
1105
1106 if (x == yFormerParent) {
1107 x.setParent(y, dataElement);
1108
1109 if (yWasLeftChild) {
1110 y.setLeft(x, dataElement);
1111 y.setRight(xFormerRightChild, dataElement);
1112 } else {
1113 y.setRight(x, dataElement);
1114 y.setLeft(xFormerLeftChild, dataElement);
1115 }
1116 } else {
1117 x.setParent(yFormerParent, dataElement);
1118
1119 if (yFormerParent != null) {
1120 if (yWasLeftChild) {
1121 yFormerParent.setLeft(x, dataElement);
1122 } else {
1123 yFormerParent.setRight(x, dataElement);
1124 }
1125 }
1126
1127 y.setLeft(xFormerLeftChild, dataElement);
1128 y.setRight(xFormerRightChild, dataElement);
1129 }
1130
1131 if (y == xFormerParent) {
1132 y.setParent(x, dataElement);
1133
1134 if (xWasLeftChild) {
1135 x.setLeft(y, dataElement);
1136 x.setRight(yFormerRightChild, dataElement);
1137 } else {
1138 x.setRight(y, dataElement);
1139 x.setLeft(yFormerLeftChild, dataElement);
1140 }
1141 } else {
1142 y.setParent(xFormerParent, dataElement);
1143
1144 if (xFormerParent != null) {
1145 if (xWasLeftChild) {
1146 xFormerParent.setLeft(y, dataElement);
1147 } else {
1148 xFormerParent.setRight(y, dataElement);
1149 }
1150 }
1151
1152 x.setLeft(yFormerLeftChild, dataElement);
1153 x.setRight(yFormerRightChild, dataElement);
1154 }
1155
1156
1157 if (x.getLeft(dataElement) != null) {
1158 x.getLeft(dataElement).setParent(x, dataElement);
1159 }
1160
1161 if (x.getRight(dataElement) != null) {
1162 x.getRight(dataElement).setParent(x, dataElement);
1163 }
1164
1165 if (y.getLeft(dataElement) != null) {
1166 y.getLeft(dataElement).setParent(y, dataElement);
1167 }
1168
1169 if (y.getRight(dataElement) != null) {
1170 y.getRight(dataElement).setParent(y, dataElement);
1171 }
1172
1173 x.swapColors(y, dataElement);
1174
1175
1176 if (rootNode[dataElement.ordinal()] == x) {
1177 rootNode[dataElement.ordinal()] = y;
1178 } else if (rootNode[dataElement.ordinal()] == y) {
1179 rootNode[dataElement.ordinal()] = x;
1180 }
1181 }
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194 private static void checkNonNullComparable(final Object o, final DataElement dataElement) {
1195 if (o == null) {
1196 throw new NullPointerException(dataElement + " cannot be null");
1197 }
1198 if (!(o instanceof Comparable)) {
1199 throw new ClassCastException(dataElement + " must be Comparable");
1200 }
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 private static void checkKey(final Object key) {
1212 checkNonNullComparable(key, KEY);
1213 }
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 private static void checkValue(final Object value) {
1224 checkNonNullComparable(value, VALUE);
1225 }
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 private static void checkKeyAndValue(final Object key, final Object value) {
1238 checkKey(key);
1239 checkValue(value);
1240 }
1241
1242
1243
1244
1245
1246
1247 private void modify() {
1248 modifications++;
1249 }
1250
1251
1252
1253
1254 private void grow() {
1255 modify();
1256 nodeCount++;
1257 }
1258
1259
1260
1261
1262 private void shrink() {
1263 modify();
1264 nodeCount--;
1265 }
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275 private void insertValue(final Node<K, V> newNode) throws IllegalArgumentException {
1276 Node<K, V> node = rootNode[VALUE.ordinal()];
1277
1278 while (true) {
1279 final int cmp = compare(newNode.getValue(), node.getValue());
1280
1281 if (cmp == 0) {
1282 throw new IllegalArgumentException(
1283 "Cannot store a duplicate value (\"" + newNode.getData(VALUE) + "\") in this Map");
1284 } else if (cmp < 0) {
1285 if (node.getLeft(VALUE) != null) {
1286 node = node.getLeft(VALUE);
1287 } else {
1288 node.setLeft(newNode, VALUE);
1289 newNode.setParent(node, VALUE);
1290 doRedBlackInsert(newNode, VALUE);
1291
1292 break;
1293 }
1294 } else {
1295 if (node.getRight(VALUE) != null) {
1296 node = node.getRight(VALUE);
1297 } else {
1298 node.setRight(newNode, VALUE);
1299 newNode.setParent(node, VALUE);
1300 doRedBlackInsert(newNode, VALUE);
1301
1302 break;
1303 }
1304 }
1305 }
1306 }
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316 private boolean doEquals(final Object obj, final DataElement dataElement) {
1317 if (obj == this) {
1318 return true;
1319 }
1320 if (obj instanceof Map == false) {
1321 return false;
1322 }
1323 final Map<?, ?> other = (Map<?, ?>) obj;
1324 if (other.size() != size()) {
1325 return false;
1326 }
1327
1328 if (nodeCount > 0) {
1329 try {
1330 for (final MapIterator<?, ?> it = getMapIterator(dataElement); it.hasNext(); ) {
1331 final Object key = it.next();
1332 final Object value = it.getValue();
1333 if (value.equals(other.get(key)) == false) {
1334 return false;
1335 }
1336 }
1337 } catch (final ClassCastException ex) {
1338 return false;
1339 } catch (final NullPointerException ex) {
1340 return false;
1341 }
1342 }
1343 return true;
1344 }
1345
1346
1347
1348
1349
1350
1351
1352 private int doHashCode(final DataElement dataElement) {
1353 int total = 0;
1354 if (nodeCount > 0) {
1355 for (final MapIterator<?, ?> it = getMapIterator(dataElement); it.hasNext(); ) {
1356 final Object key = it.next();
1357 final Object value = it.getValue();
1358 total += key.hashCode() ^ value.hashCode();
1359 }
1360 }
1361 return total;
1362 }
1363
1364
1365
1366
1367
1368
1369
1370 private String doToString(final DataElement dataElement) {
1371 if (nodeCount == 0) {
1372 return "{}";
1373 }
1374 final StringBuilder buf = new StringBuilder(nodeCount * 32);
1375 buf.append('{');
1376 final MapIterator<?, ?> it = getMapIterator(dataElement);
1377 boolean hasNext = it.hasNext();
1378 while (hasNext) {
1379 final Object key = it.next();
1380 final Object value = it.getValue();
1381 buf.append(key == this ? "(this Map)" : key)
1382 .append('=')
1383 .append(value == this ? "(this Map)" : value);
1384
1385 hasNext = it.hasNext();
1386 if (hasNext) {
1387 buf.append(", ");
1388 }
1389 }
1390
1391 buf.append('}');
1392 return buf.toString();
1393 }
1394
1395 private MapIterator<?, ?> getMapIterator(final DataElement dataElement) {
1396 switch (dataElement) {
1397 case KEY:
1398 return new ViewMapIterator(KEY);
1399 case VALUE:
1400 return new InverseViewMapIterator(VALUE);
1401 default:
1402 throw new IllegalArgumentException();
1403 }
1404 }
1405
1406
1407
1408
1409
1410 abstract class View<E> extends AbstractSet<E> {
1411
1412
1413 protected final DataElement orderType;
1414
1415
1416
1417
1418
1419
1420 View(final DataElement orderType) {
1421 super();
1422 this.orderType = orderType;
1423 }
1424
1425 @Override
1426 public int size() {
1427 return TreeBidiMap.this.size();
1428 }
1429
1430 @Override
1431 public void clear() {
1432 TreeBidiMap.this.clear();
1433 }
1434 }
1435
1436 class KeyView extends View<K> {
1437
1438
1439
1440
1441 public KeyView(final DataElement orderType) {
1442 super(orderType);
1443 }
1444
1445 @Override
1446 public Iterator<K> iterator() {
1447 return new ViewMapIterator(orderType);
1448 }
1449
1450 @Override
1451 public boolean contains(final Object obj) {
1452 checkNonNullComparable(obj, KEY);
1453 return lookupKey(obj) != null;
1454 }
1455
1456 @Override
1457 public boolean remove(final Object o) {
1458 return doRemoveKey(o) != null;
1459 }
1460
1461 }
1462
1463 class ValueView extends View<V> {
1464
1465
1466
1467
1468 public ValueView(final DataElement orderType) {
1469 super(orderType);
1470 }
1471
1472 @Override
1473 public Iterator<V> iterator() {
1474 return new InverseViewMapIterator(orderType);
1475 }
1476
1477 @Override
1478 public boolean contains(final Object obj) {
1479 checkNonNullComparable(obj, VALUE);
1480 return lookupValue(obj) != null;
1481 }
1482
1483 @Override
1484 public boolean remove(final Object o) {
1485 return doRemoveValue(o) != null;
1486 }
1487
1488 }
1489
1490
1491
1492
1493 class EntryView extends View<Map.Entry<K, V>> {
1494
1495 EntryView() {
1496 super(KEY);
1497 }
1498
1499 @Override
1500 public boolean contains(final Object obj) {
1501 if (obj instanceof Map.Entry == false) {
1502 return false;
1503 }
1504 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
1505 final Object value = entry.getValue();
1506 final Node<K, V> node = lookupKey(entry.getKey());
1507 return node != null && node.getValue().equals(value);
1508 }
1509
1510 @Override
1511 public boolean remove(final Object obj) {
1512 if (obj instanceof Map.Entry == false) {
1513 return false;
1514 }
1515 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
1516 final Object value = entry.getValue();
1517 final Node<K, V> node = lookupKey(entry.getKey());
1518 if (node != null && node.getValue().equals(value)) {
1519 doRedBlackDelete(node);
1520 return true;
1521 }
1522 return false;
1523 }
1524
1525 @Override
1526 public Iterator<java.util.Map.Entry<K, V>> iterator() {
1527 return new ViewMapEntryIterator();
1528 }
1529 }
1530
1531
1532
1533
1534 class InverseEntryView extends View<Map.Entry<V, K>> {
1535
1536 InverseEntryView() {
1537 super(VALUE);
1538 }
1539
1540 @Override
1541 public boolean contains(final Object obj) {
1542 if (obj instanceof Map.Entry == false) {
1543 return false;
1544 }
1545 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
1546 final Object value = entry.getValue();
1547 final Node<K, V> node = lookupValue(entry.getKey());
1548 return node != null && node.getKey().equals(value);
1549 }
1550
1551 @Override
1552 public boolean remove(final Object obj) {
1553 if (obj instanceof Map.Entry == false) {
1554 return false;
1555 }
1556 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
1557 final Object value = entry.getValue();
1558 final Node<K, V> node = lookupValue(entry.getKey());
1559 if (node != null && node.getKey().equals(value)) {
1560 doRedBlackDelete(node);
1561 return true;
1562 }
1563 return false;
1564 }
1565
1566 @Override
1567 public Iterator<java.util.Map.Entry<V, K>> iterator() {
1568 return new InverseViewMapEntryIterator();
1569 }
1570 }
1571
1572
1573
1574
1575
1576 abstract class ViewIterator {
1577
1578
1579 protected final DataElement orderType;
1580
1581 protected Node<K, V> lastReturnedNode;
1582
1583 protected Node<K, V> nextNode;
1584
1585 protected Node<K, V> previousNode;
1586
1587 private int expectedModifications;
1588
1589
1590
1591
1592
1593
1594 ViewIterator(final DataElement orderType) {
1595 super();
1596 this.orderType = orderType;
1597 expectedModifications = modifications;
1598 nextNode = leastNode(rootNode[orderType.ordinal()], orderType);
1599 lastReturnedNode = null;
1600 previousNode = null;
1601 }
1602
1603 public final boolean hasNext() {
1604 return nextNode != null;
1605 }
1606
1607 protected Node<K, V> navigateNext() {
1608 if (nextNode == null) {
1609 throw new NoSuchElementException();
1610 }
1611 if (modifications != expectedModifications) {
1612 throw new ConcurrentModificationException();
1613 }
1614 lastReturnedNode = nextNode;
1615 previousNode = nextNode;
1616 nextNode = nextGreater(nextNode, orderType);
1617 return lastReturnedNode;
1618 }
1619
1620 public boolean hasPrevious() {
1621 return previousNode != null;
1622 }
1623
1624 protected Node<K, V> navigatePrevious() {
1625 if (previousNode == null) {
1626 throw new NoSuchElementException();
1627 }
1628 if (modifications != expectedModifications) {
1629 throw new ConcurrentModificationException();
1630 }
1631 nextNode = lastReturnedNode;
1632 if (nextNode == null) {
1633 nextNode = nextGreater(previousNode, orderType);
1634 }
1635 lastReturnedNode = previousNode;
1636 previousNode = nextSmaller(previousNode, orderType);
1637 return lastReturnedNode;
1638 }
1639
1640 public final void remove() {
1641 if (lastReturnedNode == null) {
1642 throw new IllegalStateException();
1643 }
1644 if (modifications != expectedModifications) {
1645 throw new ConcurrentModificationException();
1646 }
1647 doRedBlackDelete(lastReturnedNode);
1648 expectedModifications++;
1649 lastReturnedNode = null;
1650 if (nextNode == null) {
1651 previousNode = greatestNode(rootNode[orderType.ordinal()], orderType);
1652 } else {
1653 previousNode = nextSmaller(nextNode, orderType);
1654 }
1655 }
1656 }
1657
1658
1659
1660
1661
1662 class ViewMapIterator extends ViewIterator implements OrderedMapIterator<K, V> {
1663
1664
1665
1666
1667 ViewMapIterator(final DataElement orderType) {
1668 super(orderType);
1669 }
1670
1671 public K getKey() {
1672 if (lastReturnedNode == null) {
1673 throw new IllegalStateException(
1674 "Iterator getKey() can only be called after next() and before remove()");
1675 }
1676 return lastReturnedNode.getKey();
1677 }
1678
1679 public V getValue() {
1680 if (lastReturnedNode == null) {
1681 throw new IllegalStateException(
1682 "Iterator getValue() can only be called after next() and before remove()");
1683 }
1684 return lastReturnedNode.getValue();
1685 }
1686
1687 public V setValue(final V obj) {
1688 throw new UnsupportedOperationException();
1689 }
1690
1691 public K next() {
1692 return navigateNext().getKey();
1693 }
1694
1695 public K previous() {
1696 return navigatePrevious().getKey();
1697 }
1698 }
1699
1700
1701
1702
1703 class InverseViewMapIterator extends ViewIterator implements OrderedMapIterator<V, K> {
1704
1705
1706
1707
1708 public InverseViewMapIterator(final DataElement orderType) {
1709 super(orderType);
1710 }
1711
1712 public V getKey() {
1713 if (lastReturnedNode == null) {
1714 throw new IllegalStateException(
1715 "Iterator getKey() can only be called after next() and before remove()");
1716 }
1717 return lastReturnedNode.getValue();
1718 }
1719
1720 public K getValue() {
1721 if (lastReturnedNode == null) {
1722 throw new IllegalStateException(
1723 "Iterator getValue() can only be called after next() and before remove()");
1724 }
1725 return lastReturnedNode.getKey();
1726 }
1727
1728 public K setValue(final K obj) {
1729 throw new UnsupportedOperationException();
1730 }
1731
1732 public V next() {
1733 return navigateNext().getValue();
1734 }
1735
1736 public V previous() {
1737 return navigatePrevious().getValue();
1738 }
1739 }
1740
1741
1742
1743
1744 class ViewMapEntryIterator extends ViewIterator implements OrderedIterator<Map.Entry<K, V>> {
1745
1746
1747
1748
1749 ViewMapEntryIterator() {
1750 super(KEY);
1751 }
1752
1753 public Map.Entry<K, V> next() {
1754 return navigateNext();
1755 }
1756
1757 public Map.Entry<K, V> previous() {
1758 return navigatePrevious();
1759 }
1760 }
1761
1762
1763
1764
1765 class InverseViewMapEntryIterator extends ViewIterator implements OrderedIterator<Map.Entry<V, K>> {
1766
1767
1768
1769
1770 InverseViewMapEntryIterator() {
1771 super(VALUE);
1772 }
1773
1774 public Map.Entry<V, K> next() {
1775 return createEntry(navigateNext());
1776 }
1777
1778 public Map.Entry<V, K> previous() {
1779 return createEntry(navigatePrevious());
1780 }
1781
1782 private Map.Entry<V, K> createEntry(final Node<K, V> node) {
1783 return new UnmodifiableMapEntry<V, K>(node.getValue(), node.getKey());
1784 }
1785 }
1786
1787
1788
1789
1790
1791
1792 static class Node<K extends Comparable<K>, V extends Comparable<V>> implements Map.Entry<K, V>, KeyValue<K, V> {
1793
1794 private final K key;
1795 private final V value;
1796 private final Node<K, V>[] leftNode;
1797 private final Node<K, V>[] rightNode;
1798 private final Node<K, V>[] parentNode;
1799 private final boolean[] blackColor;
1800 private int hashcodeValue;
1801 private boolean calculatedHashCode;
1802
1803
1804
1805
1806
1807
1808
1809
1810 @SuppressWarnings("unchecked")
1811 Node(final K key, final V value) {
1812 super();
1813 this.key = key;
1814 this.value = value;
1815 leftNode = new Node[2];
1816 rightNode = new Node[2];
1817 parentNode = new Node[2];
1818 blackColor = new boolean[] { true, true };
1819 calculatedHashCode = false;
1820 }
1821
1822 private Object getData(final DataElement dataElement) {
1823 switch (dataElement) {
1824 case KEY:
1825 return getKey();
1826 case VALUE:
1827 return getValue();
1828 default:
1829 throw new IllegalArgumentException();
1830 }
1831 }
1832
1833 private void setLeft(final Node<K, V> node, final DataElement dataElement) {
1834 leftNode[dataElement.ordinal()] = node;
1835 }
1836
1837 private Node<K, V> getLeft(final DataElement dataElement) {
1838 return leftNode[dataElement.ordinal()];
1839 }
1840
1841 private void setRight(final Node<K, V> node, final DataElement dataElement) {
1842 rightNode[dataElement.ordinal()] = node;
1843 }
1844
1845 private Node<K, V> getRight(final DataElement dataElement) {
1846 return rightNode[dataElement.ordinal()];
1847 }
1848
1849
1850
1851
1852
1853
1854
1855 private void setParent(final Node<K, V> node, final DataElement dataElement) {
1856 parentNode[dataElement.ordinal()] = node;
1857 }
1858
1859
1860
1861
1862
1863
1864
1865 private Node<K, V> getParent(final DataElement dataElement) {
1866 return parentNode[dataElement.ordinal()];
1867 }
1868
1869
1870
1871
1872
1873
1874
1875 private void swapColors(final Node<K, V> node, final DataElement dataElement) {
1876
1877 blackColor[dataElement.ordinal()] ^= node.blackColor[dataElement.ordinal()];
1878 node.blackColor[dataElement.ordinal()] ^= blackColor[dataElement.ordinal()];
1879 blackColor[dataElement.ordinal()] ^= node.blackColor[dataElement.ordinal()];
1880 }
1881
1882
1883
1884
1885
1886
1887
1888 private boolean isBlack(final DataElement dataElement) {
1889 return blackColor[dataElement.ordinal()];
1890 }
1891
1892
1893
1894
1895
1896
1897
1898 private boolean isRed(final DataElement dataElement) {
1899 return !blackColor[dataElement.ordinal()];
1900 }
1901
1902
1903
1904
1905
1906
1907 private void setBlack(final DataElement dataElement) {
1908 blackColor[dataElement.ordinal()] = true;
1909 }
1910
1911
1912
1913
1914
1915
1916 private void setRed(final DataElement dataElement) {
1917 blackColor[dataElement.ordinal()] = false;
1918 }
1919
1920
1921
1922
1923
1924
1925
1926 private void copyColor(final Node<K, V> node, final DataElement dataElement) {
1927 blackColor[dataElement.ordinal()] = node.blackColor[dataElement.ordinal()];
1928 }
1929
1930 private boolean isLeftChild(final DataElement dataElement) {
1931 return parentNode[dataElement.ordinal()] != null
1932 && parentNode[dataElement.ordinal()].leftNode[dataElement.ordinal()] == this;
1933 }
1934
1935 private boolean isRightChild(final DataElement dataElement) {
1936 return parentNode[dataElement.ordinal()] != null
1937 && parentNode[dataElement.ordinal()].rightNode[dataElement.ordinal()] == this;
1938 }
1939
1940
1941
1942
1943
1944
1945
1946 public K getKey() {
1947 return key;
1948 }
1949
1950
1951
1952
1953
1954
1955 public V getValue() {
1956 return value;
1957 }
1958
1959
1960
1961
1962
1963
1964
1965
1966 public V setValue(final V ignored) throws UnsupportedOperationException {
1967 throw new UnsupportedOperationException("Map.Entry.setValue is not supported");
1968 }
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978 @Override
1979 public boolean equals(final Object obj) {
1980 if (obj == this) {
1981 return true;
1982 }
1983 if (!(obj instanceof Map.Entry)) {
1984 return false;
1985 }
1986 final Map.Entry<?, ?> e = (Map.Entry<?, ?>) obj;
1987 return getKey().equals(e.getKey()) && getValue().equals(e.getValue());
1988 }
1989
1990
1991
1992
1993 @Override
1994 public int hashCode() {
1995 if (!calculatedHashCode) {
1996 hashcodeValue = getKey().hashCode() ^ getValue().hashCode();
1997 calculatedHashCode = true;
1998 }
1999 return hashcodeValue;
2000 }
2001 }
2002
2003
2004
2005
2006
2007 class Inverse implements OrderedBidiMap<V, K> {
2008
2009
2010 private Set<V> inverseKeySet;
2011
2012 private Set<K> inverseValuesSet;
2013
2014 private Set<Map.Entry<V, K>> inverseEntrySet;
2015
2016 public int size() {
2017 return TreeBidiMap.this.size();
2018 }
2019
2020 public boolean isEmpty() {
2021 return TreeBidiMap.this.isEmpty();
2022 }
2023
2024 public K get(final Object key) {
2025 return TreeBidiMap.this.getKey(key);
2026 }
2027
2028 public V getKey(final Object value) {
2029 return TreeBidiMap.this.get(value);
2030 }
2031
2032 public boolean containsKey(final Object key) {
2033 return TreeBidiMap.this.containsValue(key);
2034 }
2035
2036 public boolean containsValue(final Object value) {
2037 return TreeBidiMap.this.containsKey(value);
2038 }
2039
2040 public V firstKey() {
2041 if (TreeBidiMap.this.nodeCount == 0) {
2042 throw new NoSuchElementException("Map is empty");
2043 }
2044 return leastNode(TreeBidiMap.this.rootNode[VALUE.ordinal()], VALUE).getValue();
2045 }
2046
2047 public V lastKey() {
2048 if (TreeBidiMap.this.nodeCount == 0) {
2049 throw new NoSuchElementException("Map is empty");
2050 }
2051 return greatestNode(TreeBidiMap.this.rootNode[VALUE.ordinal()], VALUE).getValue();
2052 }
2053
2054 public V nextKey(final V key) {
2055 checkKey(key);
2056 final Node<K, V> node = nextGreater(TreeBidiMap.this.<V>lookup(key, VALUE), VALUE);
2057 return node == null ? null : node.getValue();
2058 }
2059
2060 public V previousKey(final V key) {
2061 checkKey(key);
2062 final Node<K, V> node = TreeBidiMap.this.nextSmaller(TreeBidiMap.this.<V>lookup(key, VALUE), VALUE);
2063 return node == null ? null : node.getValue();
2064 }
2065
2066 public K put(final V key, final K value) {
2067 final K result = get(key);
2068 TreeBidiMap.this.doPut(value, key);
2069 return result;
2070 }
2071
2072 public void putAll(final Map<? extends V, ? extends K> map) {
2073 for (final Map.Entry<? extends V, ? extends K> e : map.entrySet()) {
2074 put(e.getKey(), e.getValue());
2075 }
2076 }
2077
2078 public K remove(final Object key) {
2079 return TreeBidiMap.this.removeValue(key);
2080 }
2081
2082 public V removeValue(final Object value) {
2083 return TreeBidiMap.this.remove(value);
2084 }
2085
2086 public void clear() {
2087 TreeBidiMap.this.clear();
2088 }
2089
2090 public Set<V> keySet() {
2091 if (inverseKeySet == null) {
2092 inverseKeySet = new ValueView(VALUE);
2093 }
2094 return inverseKeySet;
2095 }
2096
2097 public Collection<K> values() {
2098 if (inverseValuesSet == null) {
2099 inverseValuesSet = new KeyView(VALUE);
2100 }
2101 return inverseValuesSet;
2102 }
2103
2104 public Set<Map.Entry<V, K>> entrySet() {
2105 if (inverseEntrySet == null) {
2106 inverseEntrySet = new InverseEntryView();
2107 }
2108 return inverseEntrySet;
2109 }
2110
2111 public OrderedMapIterator<V, K> mapIterator() {
2112 if (isEmpty()) {
2113 return EmptyOrderedMapIterator.<V, K>emptyOrderedMapIterator();
2114 }
2115 return new InverseViewMapIterator(VALUE);
2116 }
2117
2118 public OrderedBidiMap<K, V> inverseBidiMap() {
2119 return TreeBidiMap.this;
2120 }
2121
2122 @Override
2123 public boolean equals(final Object obj) {
2124 return TreeBidiMap.this.doEquals(obj, DataElement.VALUE);
2125 }
2126
2127 @Override
2128 public int hashCode() {
2129 return TreeBidiMap.this.doHashCode(DataElement.VALUE);
2130 }
2131
2132 @Override
2133 public String toString() {
2134 return TreeBidiMap.this.doToString(DataElement.VALUE);
2135 }
2136 }
2137
2138 }