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