001/*
002 * Copyright (c) 1998, 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 Torello.Java.Additional.RemoveUnsupportedIterator;
028
029import Torello.JavaDoc.LinkJavaSource;
030import Torello.JavaDoc.IntoHTMLTable;
031
032import java.util.*;
033
034import java.io.Serializable;
035
036import java.util.stream.Collector;
037
038import java.util.function.Function;
039import java.util.function.Supplier;
040import java.util.function.Predicate;
041
042/**
043 * Immutable Wrapper for <CODE>java&#46;util&#46;TreeSet</CODE>, found in the "Java Collections
044 * Framework".
045 * 
046 * <EMBED CLASS=globalDefs DATA-JDK=TreeSet>
047 * <EMBED CLASS='external-html' DATA-FILE-ID=MUCHOS_CONSTRUCTORS>
048 * <EMBED CLASS='external-html' DATA-FILE-ID=DATA_CLASS>
049 * 
050 * @param <E> the type of elements maintained by this set
051 */
052@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_MAIN")
053@SuppressWarnings("unchecked")
054public class ReadOnlyTreeSet<E>
055    implements ReadOnlyNavigableSet<E>, 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 TreeSet'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 TreeSet EMPTY_TREE_SET = new TreeSet();
072
073    // Singleton & Empty ReadOnlyTreeSet, Uses the "Supplier Constructor"
074    @SuppressWarnings("rawtypes")
075    private static final ReadOnlyTreeSet EMPTY_READONLY_TREE_SET =
076        new ReadOnlyTreeSet(null, () -> null);
077
078    // The actual TreeSet used by this instance.
079    private final TreeSet<E> treeSet;
080
081    // TRUE     => This was built using the class ROTreeSetBuilder
082    // FALSE    => This was built using the clone() of a standard java.util.TreeSet constructor
083
084    private final boolean fromBuilderOrTreeSet;
085
086    // Mimics the C++ Keyword/Concept of "Friend Class".   Is "Friends With" ROTreeSetBuilder
087    static class AccessBadge { private AccessBadge() { } }
088    private static final AccessBadge friendClassBadge = new AccessBadge();
089
090    /**
091     * Returns an empty, <B STYLE='color: red;'>singleton</B>, instance of {@code ReadOnlTreeSet}.
092     * @param <T> Returned {@link ReadOnlySet}'s Data-Type.
093     * 
094     * @return An empty set.  Since this set is both empty &amp; read-only, a raw-type singleton 
095     * will suffice for all operations offered by this clas.
096     * 
097     * <EMBED CLASS='external-html' DATA-FILE-ID=EMPTY_SYNCHRONIZED>
098     */
099    public static <T> ReadOnlyTreeSet<T> emptyROTS()
100    { return (ReadOnlyTreeSet<T>) EMPTY_READONLY_TREE_SET; }
101
102
103    // ********************************************************************************************
104    // ********************************************************************************************
105    // Basic Constructors
106    // ********************************************************************************************
107    // ********************************************************************************************
108
109
110    // To all the readers out there following along: The "AccessBadge" thing is just a slightly
111    // wimpier substitute for the C++ keyword / concept 'friend' or "Friend Class".  It means this
112    // constructor is (for all intents and purposes) a private-constructor, except for the class
113    // ROTreeSetBuilder
114    //
115    // This is the Constructor used by the Builder.  It has a "Zero-Size" Optimization
116
117    ReadOnlyTreeSet(ROTreeSetBuilder<E> rotsb, ROTreeSetBuilder.AccessBadge badge)
118    {
119        Objects.requireNonNull(badge, "Access Badge is null.  Requires Friend-Class Badge");
120
121        fromBuilderOrTreeSet = true;
122        this.treeSet = rotsb;
123    }
124
125    /**
126     * Copies parameter {@code 'c'} (and saves it) in order to guarantee that {@code 'this'}
127     * instance is Read-Only, and shielded from outside modification.
128     * 
129     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
130     * 
131     * @param c The {@code TreeSet} to be copied and saved into this instance internal
132     * and private {@code 'treeSet'} field.
133     */
134    public ReadOnlyTreeSet(Collection<E> c)
135    {
136        fromBuilderOrTreeSet = false;
137        this.treeSet = (c.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : new TreeSet<>(c);
138    }
139
140    /**
141     * Copies parameter {@code 's'} (and saves it) in order to guarantee that {@code 'this'}
142     * instance is Read-Only, and shielded from outside modification.
143     * 
144     * @param s The {@code TreeSet} to be copied and saved into this instance internal
145     * and private {@code 'treeSet'} field.
146     */
147    public ReadOnlyTreeSet(SortedSet<E> s)
148    {
149        fromBuilderOrTreeSet = false;
150        this.treeSet = (s.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : new TreeSet<>(s);
151    }
152
153    /**
154     * Use a {@code Supplier<E>} to provide an arbitrary number of elements of type {@code 'E'} 
155     * directly to this constructor.  This constructor will request elements from the
156     * {@code Supplier} provided to parameter {@code 's'} until {@code 's'} returns null.
157     *
158     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
159     * 
160     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
161     * @param s Any Java {@code Supplier<E>}
162     */
163    public ReadOnlyTreeSet(Comparator<? super E> comparator, Supplier<E> s)
164    {
165        fromBuilderOrTreeSet = false;
166
167        final TreeSet<E> treeSet = (comparator != null)
168            ? new TreeSet<>(comparator)
169            : new TreeSet<>();
170
171        E e;
172        while ((e = s.get()) != null) treeSet.add(e);
173
174        // Empty Optimization (throw away, completely, the reference, use static-constant)
175        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
176    }
177
178
179    // ********************************************************************************************
180    // ********************************************************************************************
181    // Iterable & Array Based Constructors - **NO FILTER**
182    // ********************************************************************************************
183    // ********************************************************************************************
184
185
186    /**
187     * If only a small amount of processing needs to be done on the contents of some Java
188     * Data-Type, and using an entire Builder-Class seems disproportionately complex - <I>this
189     * constructor can convert any Java {@code Iterable} into a {@code ReadOnlyTreeSet}, using
190     * a simple {@code 'mapper'}</I>.
191     * 
192     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
193     * 
194     * @param <T>        <EMBED CLASS='external-html' DATA-FILE-ID=ITERABLE_TYPE_PARAM>
195     * @param i          Any Java {@code Iterable}
196     * @param mapper     <EMBED CLASS='external-html' DATA-FILE-ID=ITERABLE_MAPPER>
197     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
198     * 
199     * @throws NullPointerException if either {@code 'i'} or {@code 'mapper'} are passed null.
200     */
201    public <T> ReadOnlyTreeSet(
202            Iterable<T> i,
203            Function<? super T, ? extends E> mapper,
204            Comparator<? super E> comparator
205        )
206    {
207        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
208
209        fromBuilderOrTreeSet = false;
210
211        final TreeSet<E> treeSet = (comparator != null)
212            ? new TreeSet<>(comparator)
213            : new TreeSet<>();
214
215        for (T t : i) treeSet.add(mapper.apply(t));
216
217        // Empty Optimization (throw away, completely, the reference, use static-constant)
218        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
219    }
220
221    /**
222     * If a Standard Java {@code Iterable} can be directly mapped into a {@code TreeSet}
223     * (and, ergo, an entire Builder-Instance would be a bit excessive) - <I>this constructor will
224     * seamlessly convert any Java {@code Iterable<E>} directly into a {@code ReadOnlyTreeSet<E>}
225     * with just this single invocation</I>.
226     * 
227     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
228     * 
229     * @param i             Any Java {@code Iterable<E>}
230     * @param comparator    <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
231     */
232    public ReadOnlyTreeSet(Iterable<E> i, Comparator<? super E> comparator)
233    {
234        fromBuilderOrTreeSet = false;
235
236        final TreeSet<E> treeSet = (comparator != null)
237            ? new TreeSet<>(comparator)
238            : new TreeSet<>();
239
240        for (E element : i) treeSet.add(element);
241
242        // Empty Optimization (throw away, completely, the reference, use static-constant)
243        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
244    }
245
246    /**
247     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
248     * {@code 'elements'}.
249     * 
250     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
251     * 
252     * @param elementsType  <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_TYPE>
253     * @param comparator    <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
254     * @param elements      <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
255     * 
256     * @throws ClassCastException   <EMBED CLASS='external-html' DATA-FILE-ID=CCEX>
257     * @throws NullPointerException If {@code 'elementsType'} is passed null.
258     */
259    public ReadOnlyTreeSet
260        (Class<E> elementsType, Comparator<? super E> comparator, Object... elements)
261    {
262        Objects.requireNonNull(elementsType, ROHelpers.NULL_MSG + "'elementsType'");
263
264        fromBuilderOrTreeSet = false;
265
266        if (elements.length == 0)
267            this.treeSet = (TreeSet<E>) EMPTY_TREE_SET;
268
269        else 
270        {
271            this.treeSet = (comparator != null)
272                ? new TreeSet<>(comparator)
273                : new TreeSet<>();
274
275            for (Object element : elements) this.treeSet.add(elementsType.cast(element));
276        }
277    }
278
279    /**
280     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
281     * {@code 'elements'}.
282     * 
283     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
284     * 
285     * @param mapper     <EMBED CLASS='external-html' DATA-FILE-ID=OBJ_E_MAPPER>
286     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
287     * @param elements   <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
288     * 
289     * @throws ClassCastException   <EMBED CLASS='external-html' DATA-FILE-ID=CCEX>
290     * @throws NullPointerException If {@code 'mapper'} is passed null.
291     */
292    public ReadOnlyTreeSet(
293            Function<Object, ? extends E>   mapper,
294            Comparator<? super E>           comparator,
295            Object...                       elements
296        )
297    {
298        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
299
300        fromBuilderOrTreeSet = false;
301
302        if (elements.length == 0)
303            this.treeSet = (TreeSet<E>) EMPTY_TREE_SET;
304
305        else 
306        {
307            this.treeSet = (comparator != null)
308                ? new TreeSet<>(comparator)
309                : new TreeSet<>();
310
311            for (Object element : elements) this.treeSet.add(mapper.apply(element));
312        }
313    }
314
315
316    // ********************************************************************************************
317    // ********************************************************************************************
318    // Iterable & Array Based Constructors - **INCLUDES ELEMENT FILTER**
319    // ********************************************************************************************
320    // ********************************************************************************************
321
322
323    /**
324     * If only a small amount of processing needs to be done on the contents of some Java
325     * Data-Type, and using an entire Builder-Class seems disproportionately complex - <I>this
326     * constructor can convert any Java {@code Iterable} into a {@code ReadOnlyTreeSet}, using
327     * a simple {@code 'mapper'}</I>.
328     * 
329     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
330     * 
331     * @param <T>        <EMBED CLASS='external-html' DATA-FILE-ID=ITERABLE_TYPE_PARAM>
332     * @param i          Any Java {@code Iterable<T>}
333     * @param mapper     <EMBED CLASS='external-html' DATA-FILE-ID=ITERABLE_MAPPER>
334     * @param filter     <EMBED CLASS='external-html' DATA-FTP=T DATA-FILE-ID=PREDICATE_FILTER>
335     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
336     * 
337     * @throws NullPointerException if any of {@code 'i'}, {@code 'mapper'} or {@code 'filter'} are
338     * passed null
339     */
340    public <T> ReadOnlyTreeSet(
341            Iterable<T>                         i,
342            Function<? super T, ? extends E>    mapper,
343            Predicate<? super T>                filter,
344            Comparator<? super E>               comparator
345        )
346    {
347        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
348        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
349
350        fromBuilderOrTreeSet = false;
351
352        final TreeSet<E> treeSet = (comparator != null)
353            ? new TreeSet<>(comparator)
354            : new TreeSet<>();
355
356        for (T t : i) if (filter.test(t)) treeSet.add(mapper.apply(t));
357
358        // Empty Optimization (throw away, completely, the reference, use static-constant)
359        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
360    }
361
362    /**
363     * If a Standard Java {@code Iterable} can be directly mapped into a {@code TreeSet}
364     * (and, ergo, an entire Builder-Instance would be a bit excessive) - <I>this constructor will
365     * seamlessly convert any Java {@code Iterable<E>} directly into a {@code ReadOnlyTreeSet<E>}
366     * with just this single invocation</I>.
367     * 
368     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
369     * 
370     * @param i          Any Java {@code Iterabler<E>}
371     * @param filter     <EMBED CLASS='external-html' DATA-FTP=E DATA-FILE-ID=PREDICATE_FILTER>
372     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
373     * 
374     * @throws NullPointerException if either {@code 'i'} or {@code 'filter'} are passed null
375     */
376    public ReadOnlyTreeSet
377        (Iterable<E> i, Predicate<? super E> filter, Comparator<? super E> comparator)
378    {
379        fromBuilderOrTreeSet = false;
380
381        final TreeSet<E> treeSet = (comparator != null)
382            ? new TreeSet<>(comparator)
383            : new TreeSet<>();
384
385        for (E element : i) if (filter.test(element)) treeSet.add(element);
386
387        // Empty Optimization (throw away, completely, the reference, use static-constant)
388        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
389    }
390
391    /**
392     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
393     * {@code 'elements'}.
394     * 
395     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
396     * 
397     * @param elementsType  <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_TYPE>
398     * @param filter        <EMBED CLASS='external-html' DATA-FTP=E DATA-FILE-ID=PREDICATE_FILTER>
399     * @param comparator    <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
400     * @param elements      <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
401     * 
402     * @throws ClassCastException <EMBED CLASS='external-html' DATA-FILE-ID=CCEX>
403     * 
404     * @throws NullPointerException If either {@code 'elementsType'} or {@code 'filter'} are passed
405     * null.
406     */
407    public ReadOnlyTreeSet(
408            Class<E>                elementsType,
409            Predicate<? super E>    filter,
410            Comparator<? super E>   comparator,
411            Object...               elements
412        )
413    {
414        Objects.requireNonNull(elementsType, ROHelpers.NULL_MSG + "'elementsType'");
415        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
416
417        fromBuilderOrTreeSet = false;
418
419        final TreeSet<E> treeSet = (comparator != null)
420            ? new TreeSet<>(comparator)
421            : new TreeSet<>();
422
423        E e;
424        for (Object element : elements)
425            if (filter.test(e = elementsType.cast(element)))
426                treeSet.add(e);
427
428        // Empty Optimization (throw away, completely, the reference, use static-constant)
429        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
430    }
431
432    /**
433     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
434     * {@code 'elements'}.
435     * 
436     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
437     * 
438     * @param mapper     <EMBED CLASS='external-html' DATA-FILE-ID=OBJ_E_MAPPER>
439     * @param filter     <EMBED CLASS='external-html' DATA-FTP=Object DATA-FILE-ID=PREDICATE_FILTER>
440     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
441     * @param elements   <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
442     * 
443     * @throws ClassCastException   <EMBED CLASS='external-html' DATA-FILE-ID=CCEX>
444     * @throws NullPointerException If either {@code 'mapper'} or {@code 'filter'} are passed null
445     */
446    public ReadOnlyTreeSet(
447            Function<Object, ? extends E>   mapper,
448            Predicate<Object>               filter,
449            Comparator<? super E>           comparator,
450            Object...                       elements
451        )
452    {
453        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
454        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
455
456        fromBuilderOrTreeSet = false;
457
458        final TreeSet<E> treeSet = (comparator != null)
459            ? new TreeSet<>(comparator)
460            : new TreeSet<>();
461
462        for (Object element : elements)
463            if (filter.test(element))
464                treeSet.add(mapper.apply(element));
465
466        // Empty Optimization (throw away, completely, the reference, use static-constant)
467        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
468    }
469
470
471    // ********************************************************************************************
472    // ********************************************************************************************
473    // @SafeVarargs / Variable-Arity / VarArgs: with Parameterized / Generic Type's
474    // ********************************************************************************************
475    // ********************************************************************************************
476
477
478    /**
479     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
480     * {@code 'elements'}.
481     * 
482     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
483     *
484     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
485     * @param elements   <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
486     */
487    @SafeVarargs
488    public ReadOnlyTreeSet(Comparator<? super E> comparator, E... elements)
489    {
490        fromBuilderOrTreeSet = false;
491
492        if (elements.length == 0)
493            this.treeSet = (TreeSet<E>) EMPTY_TREE_SET;
494
495        else 
496        {
497            this.treeSet = (comparator != null)
498                ? new TreeSet<>(comparator)
499                : new TreeSet<>();
500
501            for (E e : elements) this.treeSet.add(e);
502        }
503    }
504
505    /**
506     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
507     * {@code 'elements'}.
508     * 
509     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
510     * 
511     * @param <T>        <EMBED CLASS='external-html' DATA-FILE-ID=VARARGS_TYPE_PARAM>
512     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
513     * @param mapper     <EMBED CLASS='external-html' DATA-FILE-ID=T_ARR_E_MAPPER>
514     * @param elements   <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
515     * 
516     * @throws NullPointerException If {@code 'mapper'} is passed null.
517     */
518    @SafeVarargs
519    public <T> ReadOnlyTreeSet(
520            Comparator<? super E>               comparator,
521            Function<? super T, ? extends E>    mapper,
522            T...                                elements
523        )
524    {
525        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
526
527        fromBuilderOrTreeSet = false;
528
529        if (elements.length == 0)
530            this.treeSet = (TreeSet<E>) EMPTY_TREE_SET;
531
532        else 
533        {
534            this.treeSet = (comparator != null)
535                ? new TreeSet<>(comparator)
536                : new TreeSet<>();
537
538            for (T t : elements) this.treeSet.add(mapper.apply(t));
539        }
540    }
541
542    /**
543     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
544     * {@code 'elements'}.
545     * 
546     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
547     * 
548     * @param filter     <EMBED CLASS='external-html' DATA-FTP=E DATA-FILE-ID=PREDICATE_FILTER>
549     * @param comparator <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
550     * @param elements   <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
551     * 
552     * @throws NullPointerException If {@code 'filter'} is passed null.
553     */
554    @SafeVarargs
555    public ReadOnlyTreeSet(
556            Predicate<? super E>    filter,
557            Comparator<? super E>   comparator,
558            E...                    elements
559        )
560    {
561        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
562
563        fromBuilderOrTreeSet = false;
564
565        final TreeSet<E> treeSet = (comparator != null)
566            ? new TreeSet<>(comparator)
567            : new TreeSet<>();
568
569        for (E e : elements) if (filter.test(e)) treeSet.add(e);
570
571        // Empty Optimization (throw away, completely, the reference, use static-constant)
572        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
573    }
574
575    /**
576     * Builds {@code ReadOnlyTreeSet<E>} instance having Generic-Type {@code 'E'}, and contents
577     * {@code 'elements'}.
578     * 
579     * <EMBED CLASS='external-html' DATA-FILE-ID=TREESET_CMPR_WARN>
580     * 
581     * @param <T>           <EMBED CLASS='external-html' DATA-FILE-ID=VARARGS_TYPE_PARAM>
582     * @param filter        <EMBED CLASS='external-html' DATA-FTP=T DATA-FILE-ID=PREDICATE_FILTER>
583     * @param mapper        <EMBED CLASS='external-html' DATA-FILE-ID=T_ARR_E_MAPPER>
584     * @param comparator    <EMBED CLASS='external-html' DATA-FILE-ID=COMPARATOR>
585     * @param elements      <EMBED CLASS='external-html' DATA-FILE-ID=ELEMENTS_VAR_ARGS>
586     * 
587     * @throws NullPointerException If either {@code 'mapper'} or {@code 'filter'} are passed null
588     */
589    @SafeVarargs
590    public <T> ReadOnlyTreeSet(
591            Predicate<? super T>                filter,
592            Function<? super T, ? extends E>    mapper,
593            Comparator<? super E>               comparator,
594            T...                                elements
595        )
596    {
597        Objects.requireNonNull(mapper, ROHelpers.NULL_MSG + "'mapper'");
598        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
599
600        fromBuilderOrTreeSet = false;
601
602        final TreeSet<E> treeSet = (comparator != null)
603            ? new TreeSet<>(comparator)
604            : new TreeSet<>();
605
606        for (T t : elements) if (filter.test(t)) treeSet.add(mapper.apply(t));
607
608        // Empty Optimization (throw away, completely, the reference, use static-constant)
609        this.treeSet = (treeSet.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : treeSet;
610    }
611
612
613    // ********************************************************************************************
614    // ********************************************************************************************
615    // PRIMITIVE-ARRAY INPUT
616    // ********************************************************************************************
617    // ********************************************************************************************
618
619
620    /**
621     * Converts a Java Primitive-Array to a {@code ReadOnlyTreeSet<E>}, where {@code 'E'} is the
622     * Java Boxed-Type which corresponds to the Primitive-Array's Type.
623     *
624     * <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CTOR_DESC>
625     * @param primitiveArray        <EMBED CLASS='external-html' DATA-FILE-ID=PRIMITIVE_ARRAY>
626     * @throws ClassCastException   <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CCEX>
627     * @throws NullPointerException If {@code 'primitiveArray'} is passed null;
628     */
629    @LinkJavaSource(handle="ROHelperPrimitiveArrays", name="buildROListOrSet")
630    public ReadOnlyTreeSet(Object primitiveArray, Comparator<? super E> comparator)
631    {
632        fromBuilderOrTreeSet = false;
633
634        final TreeSet<E> ts = ROHelperPrimitiveArrays.buildROListOrSet(
635            primitiveArray,
636            (int arrayLen) -> (comparator != null) ? new TreeSet<E>(comparator) : new TreeSet<E>(),
637            null
638        );
639
640        // Empty Optimization (throw away, completely, the reference, use static-constant)
641        this.treeSet = (ts.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : ts;
642    }
643
644    /**
645     * Converts a Java Primitive-Array to a {@code ReadOnlyTreeSet<E>}, where {@code 'E'} is the
646     * Java Boxed-Type which corresponds to the Primitive-Array's Type - <I>but also accepts a 
647     * {@code 'filter'} that can remove any array-entries that need to be removed</I>.
648     *
649     * <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CTOR_DESC>
650     * @param primitiveArray        <EMBED CLASS='external-html' DATA-FILE-ID=PRIMITIVE_ARRAY>
651     * @param filter                <EMBED CLASS='external-html' DATA-FILE-ID=PRED_FILT_PRIM>
652     * @throws ClassCastException   <EMBED CLASS='external-html' DATA-FILE-ID=PRIM_ARR_CCEX>
653     * @throws NullPointerException If {@code 'primitiveArray'} is passed null;
654     */
655    @LinkJavaSource(handle="ROHelperPrimitiveArrays", name="buildROListOrSet")
656    public ReadOnlyTreeSet(
657            Object                  primitiveArray,
658            Comparator<? super E>   comparator,
659            Predicate<?>            filter
660        )
661    {
662        Objects.requireNonNull(filter, ROHelpers.NULL_MSG + "'filter'");
663
664        fromBuilderOrTreeSet = false;
665
666        final TreeSet<E> ts = ROHelperPrimitiveArrays.buildROListOrSet(
667            primitiveArray,
668            (int arrayLen) -> (comparator != null) ? new TreeSet<E>(comparator) : new TreeSet<E>(),
669            filter
670        );
671
672        // Empty Optimization (throw away, completely, the reference, use static-constant)
673        this.treeSet = (ts.size() == 0) ? ((TreeSet<E>) EMPTY_TREE_SET) : ts;
674    }
675
676
677    // ********************************************************************************************
678    // ********************************************************************************************
679    // java.util.stream.Stream HELPER
680    // ********************************************************************************************
681    // ********************************************************************************************
682
683
684    /**
685     * For use with a the Java Stream method {@code 'collect(Collector c)'}.
686     * 
687     * <EMBED CLASS='external-html' DATA-ABBREV=ts DATA-FILE-ID=STREAM_COLLECTOR>
688     * 
689     * @param <T> This is the Generic-Type of the Input-Stream.  It will also be the Generic-Type
690     * of the {@code ReadOnlyTreeSet} that's returned from the stream's {@code collect} method.
691     * 
692     * @param characteristics Optional Characteristics List.  See Java Stream-API Documentation on
693     * {@code Collector.Characteristics} inner-class for more details.
694     * 
695     * @return This returns a collector that may be piped into a stream's {@code 'collect'} method,
696     * as in the example, above.
697     */
698    public static <T> java.util.stream.Collector
699        <T, ROTreeSetBuilder<T>, ReadOnlyTreeSet<T>>
700        streamCollector(Collector.Characteristics... characteristics)
701    {
702        return Collector.of(
703            ROTreeSetBuilder<T>::new,    // The "Supplier"    (builds a new ROTreeSetBuilder)
704            ROTreeSetBuilder<T>::add,    // The "Accumulator" (adds elements to the builder)
705
706            // Oracle Making Life Difficult - It should be the line below, but, alas, it is not!
707            // ROTreeSetBuilder<T>::addAll, // The "Combiner"    (combines multiple ROTreeSetBuilders)
708            //
709            // In Stream.collect(), the 3rd parameter - the "combiner" - is a "BiConsumer<R, R>"
710            // NOTE: A "BiConsumer" is a FunctionalInterface that does not return anything - it is
711            // (obviously) a "void" return method!
712            //
713            // **BUT**
714            //
715            // In Collector.of, the 3rd parameter - the "combiner" - is a "BinaryOperation<R>"
716
717            (ROTreeSetBuilder<T> rotsb1, ROTreeSetBuilder<T> rotsb2) ->
718            {
719                rotsb1.addAll(rotsb2);
720                return rotsb1;
721            },
722
723            ROTreeSetBuilder<T>::build,  // The "Finisher"    (Converts Builder to ReadOnlyTreeSet)
724            characteristics
725        );
726    }
727
728
729    // ********************************************************************************************
730    // ********************************************************************************************
731    // Convert to java.util Types
732    // ********************************************************************************************
733    // ********************************************************************************************
734
735
736    /**
737     * Clone's {@code 'this'} instance internal {@code TreeSet<E>} field, and returns it. 
738     * <EMBED CLASS='external-html' DATA-TYPE=TreeSet DATA-FILE-ID=CLONE_TO>
739     * 
740     * @return An independent, mutable copy of {@code 'this'} instance' internal {@code TreeSet<E>}
741     * data-structure.
742     */
743    public TreeSet<E> cloneToTreeSet()
744    {
745        return fromBuilderOrTreeSet
746            ? new TreeSet<E>(this.treeSet)
747            : (TreeSet<E>) this.treeSet.clone(); 
748    }
749
750    /**
751     * <BR>Same: Identical to the method {@link #cloneToTreeSet()}.
752     * <BR>Returns: Has Return-Type {@code Set<E>}, instead.
753     * <BR>Implements: Parent-Class {@link ReadOnlySet#cloneToSet}
754     */
755    @Torello.JavaDoc.IntoHTMLTable(title="Converts this ReadOnlyTreeSet to a java.util.TreeSet")
756    public Set<E> cloneToSet() { return cloneToTreeSet(); }
757
758    // Documented in the Implemented-Interface ReadOnlySet
759    public Set<E> wrapToImmutableSet()
760    { return Collections.unmodifiableSet(this.treeSet); }
761
762
763    // ********************************************************************************************
764    // ********************************************************************************************
765    // Original JDK Methods, java.util.TreeSet
766    // ********************************************************************************************
767    // ********************************************************************************************
768
769
770    /**
771     * Returns an iterator over the elements in this set in ascending order.
772     * @return an iterator over the elements in this set in ascending order
773     */
774    public RemoveUnsupportedIterator<E> iterator()
775    { return new RemoveUnsupportedIterator<>(this.treeSet.iterator()); }
776 
777    /**
778     * Returns an iterator over the elements in this set in descending order.
779     * @return an iterator over the elements in this set in descending order
780     */
781    public RemoveUnsupportedIterator<E> descendingIterator()
782    { return new RemoveUnsupportedIterator<>(this.treeSet.descendingIterator()); }
783
784    @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet")
785    public ReadOnlyNavigableSet<E> descendingSet()
786    {
787        return new JavaHTMLReadOnlyNavigableSet<>(
788            fromBuilderOrTreeSet
789                ? ((ROTreeSetBuilder<E>) this.treeSet)._descendingSet(friendClassBadge)
790                : this.treeSet.descendingSet()
791        );
792    }
793
794    /**
795     * Returns the number of elements in this set (its cardinality).
796     * @return the number of elements in this set (its cardinality)
797     */
798    public int size()
799    { return this.treeSet.size(); }
800 
801    /**
802     * Returns {@code TRUE} if this set contains no elements.
803     * @return {@code TRUE} if this set contains no elements
804     */
805    public boolean isEmpty()
806    { return this.treeSet.isEmpty(); }
807
808    /**
809     * Returns {@code TRUE} if this set contains the specified element.  More formally, returns
810     * {@code TRUE} if and only if this set contains an element {@code e} such that
811     * {@code Objects.equals(o, e)}.
812     *
813     * @param o object to be checked for containment in this set
814     * @return {@code TRUE} if this set contains the specified element
815     * 
816     * @throws ClassCastException if the specified object cannot be compared with the elements
817     * currently in the set
818     * 
819     * @throws NullPointerException if the specified element is null and this set uses natural
820     * ordering, or its comparator does not permit null elements
821     */
822    public boolean contains(Object o)
823    { return this.treeSet.contains(o); }
824  
825    /**
826     * @throws ClassCastException {@inheritDoc}
827     * 
828     * @throws NullPointerException if {@code fromElement} or {@code toElement} is null and this
829     * set uses natural ordering, or its comparator does not permit null elements
830     * 
831     * @throws IllegalArgumentException {@inheritDoc}
832     */
833    @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet")
834    public ReadOnlyNavigableSet<E> subSet(
835            E fromElement, boolean fromInclusive,
836            E toElement,   boolean toInclusive
837        )
838    {
839        return new JavaHTMLReadOnlyNavigableSet<>(
840            fromBuilderOrTreeSet
841                ? ((ROTreeSetBuilder<E>) this.treeSet)._subSet
842                    (fromElement, fromInclusive, toElement, toInclusive, friendClassBadge)
843                : this.treeSet.subSet(fromElement, fromInclusive, toElement, toInclusive)
844        );
845    }
846
847    /**
848     * @throws ClassCastException {@inheritDoc}
849     * 
850     * @throws NullPointerException if {@code toElement} is null and this set uses natural
851     * ordering, or its comparator does not permit null elements
852     * 
853     * @throws IllegalArgumentException {@inheritDoc}
854     */
855    @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet")
856    public ReadOnlyNavigableSet<E> headSet(E toElement, boolean inclusive)
857    {
858        return new JavaHTMLReadOnlyNavigableSet<>(
859            fromBuilderOrTreeSet
860                ? ((ROTreeSetBuilder<E>) this.treeSet)._headSet
861                    (toElement, inclusive, friendClassBadge)
862                : this.treeSet.headSet(toElement, inclusive)
863        );
864    }
865
866    /**
867     * @throws ClassCastException {@inheritDoc}
868     * 
869     * @throws NullPointerException if {@code fromElement} is null and this set uses natural
870     * ordering, or its comparator does not permit null elements
871     * 
872     * @throws IllegalArgumentException {@inheritDoc}
873     */
874    @LinkJavaSource(handle="JavaHTMLReadOnlyNavigableSet")
875    public ReadOnlyNavigableSet<E> tailSet(E fromElement, boolean inclusive)
876    {
877        return new JavaHTMLReadOnlyNavigableSet<>(
878            fromBuilderOrTreeSet
879                ? ((ROTreeSetBuilder<E>) this.treeSet)._tailSet
880                    (fromElement, inclusive, friendClassBadge)
881                : this.treeSet.tailSet(fromElement, inclusive)
882        );
883    }
884 
885    /**
886     * @throws ClassCastException {@inheritDoc}
887     * 
888     * @throws NullPointerException if {@code fromElement} or {@code toElement} is null and this
889     * set uses natural ordering, or its comparator does not permit null elements
890     * 
891     * @throws IllegalArgumentException {@inheritDoc}
892     */
893    @LinkJavaSource(handle="JavaHTMLReadOnlySortedSet")
894    public ReadOnlySortedSet<E> subSet(E fromElement, E toElement)
895    {
896        return new JavaHTMLReadOnlySortedSet<>(
897            fromBuilderOrTreeSet
898                ? ((ROTreeSetBuilder<E>) this.treeSet)._subSet
899                    (fromElement, toElement, friendClassBadge)
900                : this.treeSet.subSet(fromElement, toElement)
901        );
902    }
903
904    /**
905     * @throws ClassCastException {@inheritDoc}
906     * 
907     * @throws NullPointerException if {@code toElement} is null and this set uses natural
908     * ordering, or its comparator does not permit null elements
909     * 
910     * @throws IllegalArgumentException {@inheritDoc}
911     */
912    @LinkJavaSource(handle="JavaHTMLReadOnlySortedSet")
913    public ReadOnlySortedSet<E> headSet(E toElement)
914    {
915        return new JavaHTMLReadOnlySortedSet<>(
916            fromBuilderOrTreeSet
917                ? ((ROTreeSetBuilder<E>) this.treeSet)._headSet(toElement, friendClassBadge)
918                : this.treeSet.headSet(toElement)
919        );
920    }
921
922    /**
923     * @throws ClassCastException {@inheritDoc}
924     * 
925     * @throws NullPointerException if {@code fromElement} is null and this set uses natural
926     * ordering, or its comparator does not permit null elements
927     * 
928     * @throws IllegalArgumentException {@inheritDoc}
929     */
930    @LinkJavaSource(handle="JavaHTMLReadOnlySortedSet")
931    public ReadOnlySortedSet<E> tailSet(E fromElement)
932    {
933        return new JavaHTMLReadOnlySortedSet<>(
934            fromBuilderOrTreeSet
935                ? ((ROTreeSetBuilder<E>) this.treeSet)._tailSet(fromElement, friendClassBadge)
936                : this.treeSet.tailSet(fromElement)
937        );
938    }
939 
940    public Comparator<? super E> comparator()
941    { return this.treeSet.comparator(); }
942 
943    /** @throws NoSuchElementException {@inheritDoc} */
944    public E first()
945    { return this.treeSet.first(); }
946 
947    /** @throws NoSuchElementException {@inheritDoc} */
948    public E last()
949    { return this.treeSet.last(); }
950
951    /**
952     * @throws ClassCastException {@inheritDoc}
953     * 
954     * @throws NullPointerException if the specified element is null and this set uses natural
955     * ordering, or its comparator does not permit null elements
956     */
957    public E lower(E e)
958    { return this.treeSet.lower(e); }
959
960    /**
961     * @throws ClassCastException {@inheritDoc}
962     * 
963     * @throws NullPointerException if the specified element is null and this set uses natural
964     * ordering, or its comparator does not permit null elements
965     */
966    public E floor(E e)
967    { return this.treeSet.floor(e); }
968
969    /**
970     * @throws ClassCastException {@inheritDoc}
971     * 
972     * @throws NullPointerException if the specified element is null and this set uses natural
973     * ordering, or its comparator does not permit null elements
974     */
975    public E ceiling(E e)
976    { return this.treeSet.ceiling(e); }
977
978    /**
979     * @throws ClassCastException {@inheritDoc}
980     * 
981     * @throws NullPointerException if the specified element is null and this set uses natural
982     * ordering, or its comparator does not permit null elements
983     */
984    public E higher(E e)
985    { return this.treeSet.higher(e); }
986
987    /**
988     * Utilizes the private, internal {@code java.util.TreeSet} field to generate a
989     * {@code Spliterator}.
990     * 
991     * @return a {@code Spliterator} over the elements in this set
992     */
993    public Spliterator<E> spliterator()
994    { return this.treeSet.spliterator(); }
995
996
997    // ********************************************************************************************
998    // ********************************************************************************************
999    // Misc Stuff that is defined in a super-class - for java.util, but not for Java.ReadOnly
1000    // ********************************************************************************************
1001    // ********************************************************************************************
1002
1003
1004    public boolean containsAll(Collection<?> c)
1005    { return this.treeSet.containsAll(c); }
1006
1007    public <T> T[] toArray​(T[] a)
1008    { return this.treeSet.toArray(a); }
1009
1010    public Object[] toArray()
1011    { return this.treeSet.toArray(); }
1012
1013
1014    // ********************************************************************************************
1015    // ********************************************************************************************
1016    // java.lang.Object
1017    // ********************************************************************************************
1018    // ********************************************************************************************
1019
1020
1021    /**
1022     * Returns a {@code String} representation of this {@code TreeSet}. The {@code String}
1023     * representation consists of a list of the collection's elements in the order they are
1024     * returned by its iterator, enclosed in square brackets ({@code "[]"}). Adjacent elements are
1025     * separated by the characters {@code ", "} (comma and space). Elements are converted to
1026     * {@code String's} as by {@code String.valueOf(Object)}.
1027     * 
1028     * @return a {@code String} representation of this {@code TreeSet}
1029     */
1030    public String toString()
1031    { return this.treeSet.toString(); }
1032
1033    /**
1034     * Compares the specified Object with this Set for equality, as per the definition in the 
1035     * class {@code java.util.TreeSet}.
1036     *
1037     * @param  o object to be compared for equality with this {@code ReadOnlyTreeSet}.
1038     * @return {@code TRUE} if the specified Object is equal to this set
1039     */
1040    @LinkJavaSource(handle="ROHelperEquals", name="roSetEq")
1041    public boolean equals(Object o)
1042    { return ROHelperEquals.roSetEq(this, o); }
1043
1044    /**
1045     * Returns the hash code value for this Set as per the definition in the class
1046     * {@code java.util.TreeSet}.
1047     */
1048    public int hashCode() 
1049    { return this.treeSet.hashCode(); }
1050}
1051