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&#46;util&#46;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 &amp; 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 &amp; 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}