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