001/* 002 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025package Torello.Java.ReadOnly; 026 027import java.io.Serializable; 028 029import java.util.*; 030 031import java.util.function.BiConsumer; 032import java.util.function.BiFunction; 033import java.util.function.Consumer; 034import java.util.function.Predicate; 035import java.util.function.Function; 036 037import Torello.Java.ReadOnly.ROTreeMapBuilder; 038import Torello.Java.Additional.Tuple2; 039 040import Torello.JavaDoc.Annotations.LinkJavaSource; 041import Torello.JavaDoc.Annotations.IntoHTMLTable; 042 043/** 044 * Immutable Wrapper for <CODE>java.util.TreeMap</CODE>, found in the "Java Collections 045 * Framework". 046 * 047 * <EMBED CLASS=globalDefs DATA-JDK=TreeMap> 048 * <EMBED CLASS='external-html' DATA-FILE-ID=DATA_CLASS> 049 * 050 * @param <K> the type of keys maintained by this map 051 * @param <V> the type of mapped values 052 */ 053@Torello.JavaDoc.Annotations.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_MAIN") 054@SuppressWarnings("unchecked") 055public class ReadOnlyTreeMap<K, V> 056 // extends AbstractReadOnlyMap<K, V> 057 implements ReadOnlyNavigableMap<K, V>, java.io.Serializable 058{ 059 // ******************************************************************************************** 060 // ******************************************************************************************** 061 // Protected & Private Fields, Methods, Statics 062 // ******************************************************************************************** 063 // ******************************************************************************************** 064 065 066 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 067 protected static final long serialVersionUID = 1; 068 069 // Minor Optimization where new TreeMap's that have no contents always re-use this static 070 // instance. Since this instance is completely empty, the Raw-Types things is irrelevant. 071 072 @SuppressWarnings("rawtypes") 073 private static final TreeMap EMPTY_TREE_MAP = new TreeMap(); 074 075 // Singleton & Empty ReadOnlyTreeMap, Uses the "Supplier Constructor" 076 @SuppressWarnings("rawtypes") 077 private static final ReadOnlyTreeMap EMPTY_READONLY_TREE_MAP = 078 new ReadOnlyTreeMap(EMPTY_TREE_MAP); 079 080 // The actual TreeMap used by this instance. 081 private final TreeMap<K, V> treeMap; 082 083 // TRUE => This was built using the class ROTreeMapBuilder 084 // FALSE => This was built using the clone() of a standard java.util.TreeMap constructor 085 086 private final boolean fromBuilderOrTreeMap; 087 088 // Mimics the C++ Keyword/Concept of "Friend Class". Is "Friends With" ROTreeMapBuilder 089 static class AccessBadge { private AccessBadge() { } } 090 private static final AccessBadge friendClassBadge = new AccessBadge(); 091 092 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 // Builder, Acess-Badge Constructor - and Static "Empty" getter (which is used by the builder) 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 099 100 /** 101 * Returns an empty, <B STYLE='color: red;'>singleton</B>, instance of {@code ReadOnlyTreeMap}. 102 * @param <X> Returned {@link ReadOnlyMap}'s Key-Type. 103 * @param <Y> Returned {@link ReadOnlyMap}'s Value-Type. 104 * 105 * @return An empty map. Since this map is both empty & read-only, a raw-type singleton 106 * will suffice for all operations offered by this clas. 107 * 108 * <EMBED CLASS='external-html' DATA-FILE-ID=EMPTY_SYNCHRONIZED> 109 */ 110 public static <X, Y> ReadOnlyTreeMap<X, Y> emptyROTM() 111 { return (ReadOnlyTreeMap<X, Y>) EMPTY_READONLY_TREE_MAP; } 112 113 // To all the readers out there following along: The "AccessBadge" thing is just a slightly 114 // wimpier substitute for the C++ keyword / concept 'friend' or "Friend Class". It means this 115 // constructor is (for all intents and purposes) a private-constructor, except for the class 116 // ROTreeMapBuilder 117 // 118 // This is the Constructor used by the Builder. It has a "Zero-Size" Optimization 119 120 ReadOnlyTreeMap(ROTreeMapBuilder<K, V> rotmb, ROTreeMapBuilder.AccessBadge badge) 121 { 122 Objects.requireNonNull(badge, "Access Badge is null. Requires Friend-Class Badge"); 123 124 this.fromBuilderOrTreeMap = true; 125 this.treeMap = rotmb; 126 } 127 128 129 // ******************************************************************************************** 130 // ******************************************************************************************** 131 // Modified-Original Constructors 132 // ******************************************************************************************** 133 // ******************************************************************************************** 134 135 136 /** 137 * Copies the contents of parameter {@code 'map'}, and saves saves it, thereby guaranteeing 138 * {@code 'this'} instance is Read-Only and fully-shielded from outside modification. 139 * 140 * @param map The {@code Map} to be copied into {@code 'this'} instance internal and private 141 * {@code 'treeMap'} field. 142 */ 143 public ReadOnlyTreeMap(Map<K, V> map) 144 { 145 this.fromBuilderOrTreeMap = false; 146 147 this.treeMap = (map.size() == 0) 148 ? ((TreeMap<K, V>) EMPTY_TREE_MAP) 149 : new TreeMap<K, V>(map); 150 } 151 152 /** 153 * If only a small amount of processing needs to be done on the contents of some Java 154 * Map, and using an entire Builder-Class seems disproportionately complex - <I>this 155 * constructor can convert any Java {@code Map} into a {@code ReadOnlyTreeMap}, using 156 * a simple {@code 'mapTranslator'}</I>. 157 * 158 * @param <X> The Key-Type of the User-Provided {@code Map}. 159 * @param <Y> The Value-Type of the User-Provided {@code Map}. 160 * 161 * @param refHolder This must a non-null instance of {@link Tuple2}. The provided 162 * {@code Consumer} is just that, a {@code 'Consumer'} rather than a {@code 'Function'}, since 163 * the results of each translation must be assigned to the values inside this tuple in order 164 * for them to be inserted into this {@code ReadOnlyTreeMap}. 165 * 166 * @param map Any Java {@code Map}. 167 * 168 * @param mapTranslator A function for mapping the iterated elements of Map-Types {@code 'X'} 169 * and {@code 'Y'}, into the actual {@code TreeMap's} Key-Type {@code 'K'}, and Value-Type 170 * {@code 'V'}. The results of this translation must be placed into the fields inside 171 * {@code 'refHolder'}. 172 * 173 * <BR /><BR />If this parameter is passed null, this method will throw a 174 * {@code NullPointerException}. 175 * 176 * @param filter An optional filter that can be used to prevent & prohibit any chosen 177 * elements from input {@code 'map'} from being inserted into {@code 'this'} 178 * {@code ReadOnlyTreeMap}. 179 * 180 * <BR /><BR />This parameter may be passed null, and if it is, it will be silently ignored, 181 * and all entries present inside {@code 'map'} will be processed and inserted into 182 * {@code 'this'} 183 * 184 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 185 * 186 * @throws NullPointerException if either parameter {@code 'i'} or parameter 187 * {@code 'mapTranslator'} is passed null. 188 */ 189 public <X, Y> ReadOnlyTreeMap( 190 Tuple2<K, V> refHolder, 191 Map<X, Y> map, 192 Consumer<Map.Entry<X, Y>> mapTranslator, 193 Predicate<Map.Entry<X, Y>> filter, 194 Comparator<? super K> comparator 195 ) 196 { 197 Objects.requireNonNull(refHolder, ROHelpers.NULL_MSG + "'refHolder'"); 198 Objects.requireNonNull(mapTranslator, ROHelpers.NULL_MSG + "'mapTranslator'"); 199 200 fromBuilderOrTreeMap = false; 201 202 TreeMap<K, V> treeMap = (comparator != null) 203 ? new TreeMap<>(comparator) 204 : new TreeMap<>(); 205 206 if (filter == null) 207 208 for (Map.Entry<X, Y> entry : map.entrySet()) 209 { 210 mapTranslator.accept(entry); 211 treeMap.put(refHolder.a, refHolder.b); 212 } 213 214 else for (Map.Entry<X, Y> entry : map.entrySet()) 215 { 216 if (! filter.test(entry)) continue; 217 mapTranslator.accept(entry); 218 treeMap.put(refHolder.a, refHolder.b); 219 } 220 221 // Empty Optimization (throw away, completely, the reference, use static-constant) 222 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 223 } 224 225 226 // ******************************************************************************************** 227 // ******************************************************************************************** 228 // New Constructors, January 2024 229 // ******************************************************************************************** 230 // ******************************************************************************************** 231 232 233 /** 234 * Constructs an instance of {@code ReadOnlyTreeMap} that contains the keys present in 235 * parameter {@code 'keys'}, and values generated by {@code 'valueMapper'} - using each of the 236 * {@code 'keys'} as input. 237 * 238 * <EMBED CLASS='external-html' DATA-FILE-ID=LOOK_AT_IT> 239 * 240 * @param keys Any Java {@code Iterable} instance. 241 * @param valueMapper A user provided function to compute a map value, based on a map key. 242 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=MAP_ITERABLE_FILTER> 243 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 244 * 245 * @throws NullPointerException if either {@code 'keys'} or {@code 'valueMapper'} are passed 246 * null. 247 */ 248 public ReadOnlyTreeMap( 249 Iterable<? extends K> keys, 250 Function<? super K, ? extends V> valueMapper, 251 Predicate<? super K> filter, 252 Comparator<? super K> comparator 253 ) 254 { 255 Objects.requireNonNull(keys, ROHelpers.NULL_MSG + "'keys'"); 256 Objects.requireNonNull(valueMapper, ROHelpers.NULL_MSG + "'valueMapper'"); 257 258 fromBuilderOrTreeMap = false; 259 260 TreeMap<K, V> treeMap = (comparator != null) 261 ? new TreeMap<>(comparator) 262 : new TreeMap<>(); 263 264 if (filter == null) 265 for (K key : keys) 266 treeMap.put(key, valueMapper.apply(key)); 267 268 else 269 for (K key : keys) 270 if (filter.test(key)) 271 treeMap.put(key, valueMapper.apply(key)); 272 273 // Empty Optimization (throw away, completely, the reference, use static-constant) 274 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 275 } 276 277 /** 278 * Constructs an instance of {@code ReadOnlyTreeMap} that has been populated by the Key-Value 279 * Pairs left in {@code 'refHolder'} by each invocation of the {@code Runnable} parameter 280 * {@code 'computeNextEntry'}. Key-Value Pairs are inserted until an invocation of the 281 * {@code Runnable} leaves null in {@code refHolder.a} and {@code refHolder.b} 282 * 283 * <EMBED CLASS='external-html' DATA-FILE-ID=LOOK_AT_IT> 284 * 285 * @param refHolder <EMBED CLASS='external-html' DATA-FILE-ID=REF_HOLDER> 286 * @param computeNextEntry <EMBED CLASS='external-html' DATA-FILE-ID=COMPUTE_NEXT_RUN> 287 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 288 * 289 * @throws NullPointerException if either {@code 'refHolder'} or {@code 'computeNextEntry'} are 290 * passed null. 291 */ 292 public ReadOnlyTreeMap( 293 Tuple2<K, V> refHolder, 294 Runnable computeNextEntry, 295 Comparator<? super K> comparator 296 ) 297 { 298 Objects.requireNonNull(refHolder, ROHelpers.NULL_MSG + "'refHolder'"); 299 Objects.requireNonNull(computeNextEntry, ROHelpers.NULL_MSG + "'computeNextEntry'"); 300 301 fromBuilderOrTreeMap = false; 302 303 TreeMap<K, V> treeMap = (comparator != null) 304 ? new TreeMap<>(comparator) 305 : new TreeMap<>(); 306 307 do 308 { 309 computeNextEntry.run(); 310 if ((refHolder.a == null) && (refHolder.b == null)) break; 311 treeMap.put(refHolder.a, refHolder.b); 312 } 313 while (true); 314 315 // Empty Optimization (throw away, completely, the reference, use static-constant) 316 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 317 } 318 319 /** 320 * Populates an instance of {@code ReadOnlyTreeMap} by iterating the input {@code 'source'} 321 * iterable, and passing each value returned by that {@code Iterator} to the 322 * {@code 'computeNextEntry'} Java {@code Consumer}. 323 * 324 * <BR /><BR />It is the programmer's responsibility to properly place each Key-Value Pair 325 * that is intending to be inserted into the final {@code Map} instance into the 326 * {@code 'refHolder'} instance. After each invocation of {@code 'computeNextEntry'}, this 327 * constructor's logic will retrieve the values within {@code 'refHolder.a'} and 328 * {@code 'refHolder.b'} and insert them into this instance internal {@code TreeMap}. 329 * 330 * <EMBED CLASS='external-html' DATA-FILE-ID=LOOK_AT_IT> 331 * 332 * @param <X> The type of the elements inside {@code 'source'} 333 * @param source Any Java {@code Iterable} instance. 334 * @param refHolder <EMBED CLASS='external-html' DATA-FILE-ID=REF_HOLDER> 335 * @param computeNextEntry <EMBED CLASS='external-html' DATA-FILE-ID=COMPUTE_NEXT_CONS> 336 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=MAP_ITERABLE_FILTER> 337 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 338 * 339 * @throws NullPointerException if either {@code 'refHolder'}, {@code 'computeNextEntry'} or 340 * {@code 'source'} are passed null. 341 */ 342 public <X> ReadOnlyTreeMap( 343 Iterable<X> source, 344 Tuple2<K, V> refHolder, 345 Consumer<? super X> computeNextEntry, 346 Predicate<? super X> filter, 347 Comparator<? super K> comparator 348 ) 349 { 350 Objects.requireNonNull(refHolder, ROHelpers.NULL_MSG + "'refHolder'"); 351 Objects.requireNonNull(computeNextEntry, ROHelpers.NULL_MSG + "'computeNextEntry'"); 352 353 fromBuilderOrTreeMap = false; 354 355 TreeMap<K, V> treeMap = (comparator != null) 356 ? new TreeMap<>(comparator) 357 : new TreeMap<>(); 358 359 X x; // temp var 360 Iterator<X> iter = source.iterator(); 361 362 if (filter == null) 363 364 while (iter.hasNext()) 365 { 366 computeNextEntry.accept(iter.next()); 367 treeMap.put(refHolder.a, refHolder.b); 368 } 369 370 else 371 372 while (iter.hasNext()) 373 if (filter.test(x = iter.next())) 374 { 375 computeNextEntry.accept(x); 376 treeMap.put(refHolder.a, refHolder.b); 377 } 378 379 // Empty Optimization (throw away, completely, the reference, use static-constant) 380 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 381 } 382 383 384 // ******************************************************************************************** 385 // ******************************************************************************************** 386 // Array Constructors, March 2024 387 // ******************************************************************************************** 388 // ******************************************************************************************** 389 390 391 /** 392 * Retrieves elements from the VarArgs Generic-Array parameter {@code 'elements'}, and 393 * subsequently invokes the {@code 'computeNextEntry'} processor to populate this 394 * {@code ReadOnlyTreeMap}. 395 * 396 * @param <X> The type of array parameter {@code 'elements'} 397 * @param refHolder <EMBED CLASS='external-html' DATA-FILE-ID=REF_HOLDER> 398 * @param computeNextEntry <EMBED CLASS='external-html' DATA-FILE-ID=ARR_COMPUTE_NEXT_CONS> 399 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=MAP_ARRAY_FILTER> 400 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 401 * @param elements Any Generic VarArgs-Array 402 * @throws ClassCastException <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CCEX> 403 * 404 * @throws NullPointerException if either {@code 'refHolder'} or {@code 'computeNextEntry'} 405 * are passed null 406 */ 407 public <X> ReadOnlyTreeMap( 408 Tuple2<K, V> refHolder, 409 Consumer<? super X> computeNextEntry, 410 Predicate<? super X> filter, 411 Comparator<? super K> comparator, 412 X... elements 413 ) 414 { 415 Objects.requireNonNull(refHolder, ROHelpers.NULL_MSG + "'refHolder'"); 416 Objects.requireNonNull(computeNextEntry, ROHelpers.NULL_MSG + "'computeNextEntry'"); 417 418 this.fromBuilderOrTreeMap = false; 419 420 TreeMap<K, V> treeMap = (comparator != null) ? new TreeMap<>(comparator) : new TreeMap<>(); 421 422 if (filter == null) for (X e : elements) 423 { 424 computeNextEntry.accept(e); 425 treeMap.put(refHolder.a, refHolder.b); 426 } 427 428 else for (X x : elements) if (filter.test(x)) 429 { 430 computeNextEntry.accept(x); 431 treeMap.put(refHolder.a, refHolder.b); 432 } 433 434 // Empty Optimization (throw away, completely, the reference, use static-constant) 435 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 436 } 437 438 /** 439 * Retrieves elements from the Java Primitive-Array parameter {@code 'primitiveArray'}, and 440 * subsequently invokes the {@code 'computeNextEntry'} processor to populate this 441 * {@code ReadOnlyTreeMap}. 442 * 443 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=PRED_FILT_PRIM> 444 * @param computeNextEntry <EMBED CLASS='external-html' DATA-FILE-ID=ARR_COMPUTE_NEXT_CONS> 445 * @param refHolder <EMBED CLASS='external-html' DATA-FILE-ID=REF_HOLDER> 446 * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR> 447 * @param primitiveArray Any Java Primitive-Array 448 * @throws ClassCastException <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CCEX> 449 * 450 * @throws NullPointerException if either {@code 'refHolder'} or {@code 'computeNextEntry'} 451 * are passed null 452 * 453 */ 454 public <X> ReadOnlyTreeMap( 455 Predicate<?> filter, 456 Consumer<?> computeNextEntry, 457 Tuple2<K, V> refHolder, 458 Comparator<? super K> comparator, 459 Object primitiveArray 460 ) 461 { 462 Objects.requireNonNull(refHolder, ROHelpers.NULL_MSG + "'refHolder'"); 463 Objects.requireNonNull(computeNextEntry, ROHelpers.NULL_MSG + "'computeNextEntry'"); 464 465 this.fromBuilderOrTreeMap = false; 466 467 TreeMap<K, V> treeMap = ROHelperPrimitiveArrays.buildROMap( 468 primitiveArray, 469 (int arrayLen) -> (comparator != null) ? new TreeMap<>(comparator) : new TreeMap<>(), 470 filter, 471 refHolder, 472 computeNextEntry 473 ); 474 475 // Empty Optimization (throw away, completely, the reference, use static-constant) 476 this.treeMap = (treeMap.size() == 0) ? ((TreeMap<K, V>) EMPTY_TREE_MAP) : treeMap; 477 } 478 479 480 // ******************************************************************************************** 481 // ******************************************************************************************** 482 // Convert to java.util Types 483 // ******************************************************************************************** 484 // ******************************************************************************************** 485 486 487 /** 488 * Clone's {@code 'this'} instance internal {@code TreeMap<K, V>} field, and returns it. 489 * <EMBED CLASS='external-html' DATA-TYPE=TreeMap DATA-FILE-ID=CLONE_TO> 490 * 491 * @return An independent, mutable copy of {@code 'this'} instance internal 492 * {@code TreeMap<K, V>} data-structure. 493 */ 494 public TreeMap<K, V> cloneToTreeMapOLD() 495 { 496 if (! fromBuilderOrTreeMap) return (TreeMap<K, V>) this.treeMap.clone(); 497 498 TreeMap<K, V> ret = new TreeMap<K, V>(); 499 500 for (Map.Entry<K, V> e : 501 ((ROTreeMapBuilder<K, V>) this.treeMap)._entrySet(friendClassBadge)) 502 503 ret.put(e.getKey(), e.getValue()); 504 505 return ret; 506 } 507 508 509 // ******************************************************************************************** 510 // ******************************************************************************************** 511 // Original JDK Methods, java.util.TreeMap 512 // ******************************************************************************************** 513 // ******************************************************************************************** 514 515 516 /** 517 * Returns the number of key-value mappings in this map. 518 * @return the number of key-value mappings in this map 519 */ 520 public int size() 521 { return this.treeMap.size(); } 522 523 /** 524 * Returns {@code TRUE} if this map contains a mapping for the specified key. 525 * 526 * @param key key whose presence in this map is to be tested 527 * @return {@code TRUE} if this map contains a mapping for the specified key 528 * 529 * @throws ClassCastException if the specified key cannot be compared with the keys currently 530 * in the map 531 * 532 * @throws NullPointerException if the specified key is null and this map uses natural 533 * ordering, or its comparator does not permit null keys 534 */ 535 public boolean containsKey(Object key) 536 { return this.treeMap.containsKey(key); } 537 538 /** 539 * Returns {@code TRUE} if this map maps one or more keys to the specified value. More 540 * formally, returns {@code TRUE} if and only if this map contains at least one mapping to a 541 * value {@code v} such that {@code (value==null ? v==null : value.equals(v))}. 542 * 543 * @param value value whose presence in this map is to be tested 544 * @return {@code TRUE} if a mapping to {@code value} exists; {@code FALSE} otherwise 545 */ 546 public boolean containsValue(Object value) 547 { return this.treeMap.containsValue(value); } 548 549 /** 550 * Returns the value to which the specified key is mapped, or {@code null} if this map contains 551 * no mapping for the key. 552 * 553 * <BR /><BR />More formally, if this map contains a mapping from a key {@code k} to a value 554 * {@code v} such that {@code key} compares equal to {@code k} according to the map's ordering, 555 * then this method returns {@code v}; otherwise it returns {@code null}. (There can be at 556 * most one such mapping.) 557 * 558 * <BR /><BR />A return value of {@code null} does not <em>necessarily</em> indicate that the 559 * map contains no mapping for the key; it's also possible that the map explicitly maps the key 560 * to {@code null}. The {@link #containsKey containsKey} operation may be used to distinguish 561 * these two cases. 562 * 563 * @throws ClassCastException if the specified key cannot be compared with the keys currently 564 * in the map 565 * 566 * @throws NullPointerException if the specified key is null and this map uses natural 567 * ordering, or its comparator does not permit null keys 568 */ 569 public V get(Object key) 570 { return this.treeMap.get(key); } 571 572 public Comparator<? super K> comparator() 573 { return this.treeMap.comparator(); } 574 575 /** @throws NoSuchElementException {@inheritDoc} */ 576 public K firstKey() 577 { return this.treeMap.firstKey(); } 578 579 /** @throws NoSuchElementException {@inheritDoc} */ 580 public K lastKey() 581 { return this.treeMap.lastKey(); } 582 583 public ReadOnlyMap.Entry<K,V> firstEntry() 584 { return new EntryImpl<>(this.treeMap.firstEntry()); } 585 586 public ReadOnlyMap.Entry<K,V> lastEntry() 587 { return new EntryImpl<>(this.treeMap.lastEntry()); } 588 589 /** 590 * @throws ClassCastException {@inheritDoc} 591 * 592 * @throws NullPointerException if the specified key is null and this map uses natural 593 * ordering, or its comparator does not permit null keys 594 */ 595 public ReadOnlyMap.Entry<K,V> lowerEntry(K key) 596 { return new EntryImpl<>(this.treeMap.lowerEntry(key)); } 597 598 /** 599 * @throws ClassCastException {@inheritDoc} 600 * 601 * @throws NullPointerException if the specified key is null and this map uses natural 602 * ordering, or its comparator does not permit null keys 603 */ 604 public K lowerKey(K key) 605 { return this.treeMap.lowerKey(key); } 606 607 /** 608 * @throws ClassCastException {@inheritDoc} 609 * 610 * @throws NullPointerException if the specified key is null and this map uses natural 611 * ordering, or its comparator does not permit null keys 612 */ 613 public ReadOnlyMap.Entry<K,V> floorEntry(K key) 614 { return new EntryImpl<>(this.treeMap.floorEntry(key)); } 615 616 /** 617 * @throws ClassCastException {@inheritDoc} 618 * 619 * @throws NullPointerException if the specified key is null and this map uses natural 620 * ordering, or its comparator does not permit null keys 621 */ 622 public K floorKey(K key) 623 { return this.treeMap.floorKey(key); } 624 625 /** 626 * @throws ClassCastException {@inheritDoc} 627 * 628 * @throws NullPointerException if the specified key is null and this map uses natural 629 * ordering, or its comparator does not permit null keys 630 */ 631 public ReadOnlyMap.Entry<K,V> ceilingEntry(K key) 632 { return new EntryImpl<>(this.treeMap.ceilingEntry(key)); } 633 634 /** 635 * @throws ClassCastException {@inheritDoc} 636 * 637 * @throws NullPointerException if the specified key is null and this map uses natural 638 * ordering, or its comparator does not permit null keys 639 */ 640 public K ceilingKey(K key) 641 { return this.treeMap.ceilingKey(key); } 642 643 /** 644 * @throws ClassCastException {@inheritDoc} 645 * 646 * @throws NullPointerException if the specified key is null and this map uses natural 647 * ordering, or its comparator does not permit null keys 648 */ 649 public ReadOnlyMap.Entry<K,V> higherEntry(K key) 650 { return new EntryImpl<>(this.treeMap.higherEntry(key)); } 651 652 /** 653 * @throws ClassCastException {@inheritDoc} 654 * 655 * @throws NullPointerException if the specified key is null and this map uses natural 656 * ordering, or its comparator does not permit null keys 657 */ 658 public K higherKey(K key) 659 { return this.treeMap.higherKey(key); } 660 661 /** Returns a {@link ReadOnlySet} view of the keys contained in this map. */ 662 @LinkJavaSource(handle="JavaHTMLReadOnlySet") 663 public ReadOnlySet<K> keySet() 664 { 665 return new JavaHTMLReadOnlySet<>( 666 fromBuilderOrTreeMap 667 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._keySet(friendClassBadge) 668 : this.treeMap.keySet() 669 ); 670 } 671 672 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet") 673 public ReadOnlyNavigableSet<K> navigableKeySet() 674 { 675 return new JavaHTMLReadOnlyNavigableSet<>( 676 fromBuilderOrTreeMap 677 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._navigableKeySet(friendClassBadge) 678 : this.treeMap.navigableKeySet() 679 ); 680 } 681 682 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet") 683 public ReadOnlyNavigableSet<K> descendingKeySet() 684 { 685 return new JavaHTMLReadOnlyNavigableSet<>( 686 fromBuilderOrTreeMap 687 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._descendingKeySet(friendClassBadge) 688 : this.treeMap.descendingKeySet() 689 ); 690 } 691 692 /** Returns a {@link ReadOnlyCollection} view of the values contained in this map. */ 693 @LinkJavaSource(handle="JavaHTMLReadOnlyCollection") 694 public ReadOnlyCollection<V> values() 695 { 696 return new JavaHTMLReadOnlyCollection<>( 697 fromBuilderOrTreeMap 698 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._values(friendClassBadge) 699 : this.treeMap.values() 700 ); 701 } 702 703 /** 704 * Returns a {@link ReadOnlySet} view of the mappings contained in this map. 705 * 706 * @return At the moment, a {@link ReadOnlyTreeSet} is arbitrarily used for the type of the 707 * returned instance 708 */ 709 @LinkJavaSource(handle="ROHelperEntrySet") 710 public ReadOnlySet<ReadOnlyMap.Entry<K, V>> entrySet() 711 { 712 return ROHelperEntrySet.toReadOnlyEntrySet( 713 fromBuilderOrTreeMap 714 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._entrySet(friendClassBadge) 715 : this.treeMap.entrySet() 716 ); 717 } 718 719 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableMap") 720 public ReadOnlyNavigableMap<K, V> descendingMap() 721 { 722 return new JavaHTMLReadOnlyNavigableMap<>( 723 fromBuilderOrTreeMap 724 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._descendingMap(friendClassBadge) 725 : this.treeMap.descendingMap() 726 ); 727 } 728 729 /** 730 * @throws ClassCastException {@inheritDoc} 731 * 732 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null and this map uses 733 * natural ordering, or its comparator does not permit null keys 734 * 735 * @throws IllegalArgumentException {@inheritDoc} 736 */ 737 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableMap") 738 public ReadOnlyNavigableMap<K,V> subMap( 739 K fromKey, boolean fromInclusive, 740 K toKey, boolean toInclusive 741 ) 742 { 743 return new JavaHTMLReadOnlyNavigableMap<>( 744 fromBuilderOrTreeMap 745 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._subMap 746 (fromKey, fromInclusive, toKey, toInclusive, friendClassBadge) 747 : this.treeMap.subMap(fromKey, fromInclusive, toKey, toInclusive) 748 ); 749 } 750 751 /** 752 * @throws ClassCastExceptionv{@inheritDoc} 753 * 754 * @throws NullPointerException if {@code toKey} is nullvand this map uses natural ordering, or 755 * its comparator does not permit null keys 756 * 757 * @throws IllegalArgumentException {@inheritDoc} 758 */ 759 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableMap") 760 public ReadOnlyNavigableMap<K,V> headMap(K toKey, boolean inclusive) 761 { 762 return new JavaHTMLReadOnlyNavigableMap<>( 763 fromBuilderOrTreeMap 764 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._headMap 765 (toKey, inclusive, friendClassBadge) 766 : this.treeMap.headMap(toKey, inclusive) 767 ); 768 } 769 770 /** 771 * @throws ClassCastException {@inheritDoc} 772 * 773 * @throws NullPointerException if {@code fromKey} is null and this map uses natural ordering, 774 * or its comparator does not permit null keys 775 * 776 * @throws IllegalArgumentException {@inheritDoc} 777 */ 778 @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableMap") 779 public ReadOnlyNavigableMap<K,V> tailMap(K fromKey, boolean inclusive) 780 { 781 return new JavaHTMLReadOnlyNavigableMap<>( 782 fromBuilderOrTreeMap 783 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._tailMap 784 (fromKey, inclusive, friendClassBadge) 785 : this.treeMap.tailMap(fromKey, inclusive) 786 ); 787 } 788 789 /** 790 * @throws ClassCastException {@inheritDoc} 791 * 792 * @throws NullPointerException if {@code fromKey} or {@code toKey} is null and this map uses 793 * natural ordering, or its comparator does not permit null keys 794 * 795 * @throws IllegalArgumentException {@inheritDoc} 796 */ 797 @LinkJavaSource(handle="JavaHTMLReadOnlySortedMap") 798 public ReadOnlySortedMap<K,V> subMap(K fromKey, K toKey) 799 { 800 return new JavaHTMLReadOnlySortedMap<>( 801 fromBuilderOrTreeMap 802 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._subMap 803 (fromKey, toKey, friendClassBadge) 804 : this.treeMap.subMap(fromKey, toKey) 805 ); 806 } 807 808 /** 809 * @throws ClassCastException {@inheritDoc} 810 * 811 * @throws NullPointerException if {@code toKey} is null and this map uses natural ordering, or 812 * its comparator does not permit null keys 813 * 814 * @throws IllegalArgumentException {@inheritDoc} 815 */ 816 @LinkJavaSource(handle="JavaHTMLReadOnlySortedMap") 817 public ReadOnlySortedMap<K,V> headMap(K toKey) 818 { 819 return new JavaHTMLReadOnlySortedMap<>( 820 fromBuilderOrTreeMap 821 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._headMap(toKey, friendClassBadge) 822 : this.treeMap.headMap(toKey) 823 ); 824 } 825 826 /** 827 * @throws ClassCastException {@inheritDoc} 828 * 829 * @throws NullPointerException if {@code fromKey} is null and this map uses natural ordering, 830 * or its comparator does not permit null keys 831 * 832 * @throws IllegalArgumentException {@inheritDoc} 833 */ 834 @LinkJavaSource(handle="JavaHTMLReadOnlySortedMap") 835 public ReadOnlySortedMap<K,V> tailMap(K fromKey) 836 { 837 return new JavaHTMLReadOnlySortedMap<>( 838 fromBuilderOrTreeMap 839 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._tailMap(fromKey, friendClassBadge) 840 : this.treeMap.tailMap(fromKey) 841 ); 842 } 843 844 @Override 845 public void forEach(BiConsumer<? super K, ? super V> action) 846 { this.treeMap.forEach(action); } 847 848 849 // ******************************************************************************************** 850 // ******************************************************************************************** 851 // Misc Stuff that is defined in a super-class - for java.util, but not for Java.ReadOnly 852 // ******************************************************************************************** 853 // ******************************************************************************************** 854 855 856 public boolean isEmpty() 857 { return this.treeMap.isEmpty(); } 858 859 860 // ******************************************************************************************** 861 // ******************************************************************************************** 862 // Convert to java.util Types 863 // ******************************************************************************************** 864 // ******************************************************************************************** 865 866 867 /** 868 * Clone's {@code 'this'} instance internal {@code TreeMap<K, V>} field, and returns it. 869 * <EMBED CLASS='external-html' DATA-TYPE=TreeMap DATA-FILE-ID=CLONE_TO> 870 * 871 * @return An independent, mutable copy of {@code 'this'} instance' internal 872 * {@code TreeMap<K, V>} data-structure. 873 */ 874 public TreeMap<K, V> cloneToTreeMap() 875 { 876 return fromBuilderOrTreeMap 877 ? new TreeMap<K, V>(this.treeMap) 878 : (TreeMap<K, V>) this.treeMap.clone(); 879 } 880 881 /** 882 * <BR>Same: Identical to the method {@link #cloneToTreeMap()}. 883 * <BR>Returns: Has Return-Type {@code Map<K, V>}, instead. 884 * <BR>Implements: Parent-Class {@link ReadOnlyMap#cloneToMap} 885 */ 886 @IntoHTMLTable(title="Converts this ReadOnlyTreeMap to a java.util.TreeMap") 887 public Map<K, V> cloneToMap() { return cloneToTreeMap(); } 888 889 // Documented in the Implemented-Interface ReadOnlyMap 890 public Map<K, V> wrapToImmutableMap() 891 { return Collections.unmodifiableMap(this.treeMap); } 892 893 894 // ******************************************************************************************** 895 // ******************************************************************************************** 896 // java.lang.Object 897 // ******************************************************************************************** 898 // ******************************************************************************************** 899 900 901 /** 902 * Returns a {@code String} representation of this map. The {@code String} representation 903 * consists of a list of key-value mappings in the order returned by the map's entrySet view's 904 * iterator, enclosed in braces ({@code "{}"}). Adjacent mappings are separated by the 905 * characters {@code ", "} (comma and space). Each key-value mapping is rendered as the key 906 * followed by an equals sign ({@code "="}) followed by the associated value. Keys and values 907 * are converted to {@code String's} as by {@code String.valueOf(Object)}. 908 * 909 * @return a {@code String} representation of this {@code TreeMap} 910 */ 911 @LinkJavaSource(handle="ROHelperEntrySet") 912 public String toString() 913 { 914 return ROHelperEntrySet.toString( 915 this.treeMap, // if the map contains itself, it is needed for printing purposes 916 fromBuilderOrTreeMap 917 ? ((ROTreeMapBuilder<K, V>) this.treeMap)._entrySet(friendClassBadge) 918 : this.treeMap.entrySet() 919 ); 920 } 921 922 /** 923 * Compares the specified Object with this Map for equality, as per the definition in the 924 * class {@code java.util.TreeMap}. 925 * 926 * @param o object to be compared for equality with this {@code ReadOnlyTreeMap}. 927 * @return {@code TRUE} if the specified Object is equal to this map 928 */ 929 @LinkJavaSource(handle="ROHelperEquals", name="roMapEq") 930 public boolean equals(Object o) 931 { return ROHelperEquals.roMapEq(this, o); } 932 933 /** 934 * Returns the hash code value for this Map as per the definition in the class 935 * {@code java.util.TreeMap}. 936 */ 937 public int hashCode() 938 { return this.treeMap.hashCode(); } 939 940}