Class ROPropertiesBuilder

  • All Implemented Interfaces:
    java.io.Serializable, java.lang.Cloneable, java.util.Map<java.lang.Object,​java.lang.Object>

    public final class ROPropertiesBuilder
    extends java.util.Properties
    implements java.lang.Cloneable, java.io.Serializable
    This class was originally copied from GitHub's Open-JDK Account. Though the original file has been modified, few changes were applied to the Javadoc Commenting. Method and parameter names & types have not been modified whatsoever. This file may be viewed on the GitHub Archive for Java Package java.util.*

    The Original '.java' Source-File's Header-Copyright Information is included here: File Copyright. Within that Copyright Notice, it is suggested that a copy of the GNU Public License V2 also be included alongside.
    A Copy of Java's Properties class; used for building a ReadOnlyProperties. Maintains an internal and inaccessible Properties instance. Upon build completion, this instance is passed to the ReadOnlyProperties instance and stored there.

    The internal data-structure is not exposed by any method provided in this API. It is guaranteed that the contents of a ReadOnlyProperties will not be modified.

    Note: The "RO Builder Classes" are somewhat superfluous (a little)

    The art of any solid "Read-Only" Data-Structure Class-API is providing an intelligent means of actually inserting Data into a supposedly-read-only class. In this package, the most direct and efficient way of doing so is just to use one of the myriad constructors offered by the ReadOnly Data-Classes.

    Another sound way of creating any "ReadOnly-XX" Data-Structure, is to simply populate the corresponding java.util.XX class instance, and pass that instance your ReadOnly-X Constructor. The constructor actually copies the data out of the original structure, and saves it to its own private & internal data-structure in order to guarantee the immutability contract.

    But what about a situation where there is a Properties that is being populated by a very large number elements? It would likely be of benefit to skip the data-copying step for performance reasons! If so, then a builder can improve performance quite a bit. The real value of using a "Builder" rather than one of the ReadOnlyProperties constructors is that this Builder's build() method doesn't actually have any kind of data-copy step at all!

    Also, of some interest, is that this class inherits the original Java-Class java.util.Properties (explained further, below), making it extremely easy to use.


    Inherits java.util.Properties
    This class may be passed to any Data-Building Method that accepts a Properties, because it inherits from that class. Any implementation that can populate a Properties can also populate this builder.

    Efficiency Improvement:
    This class is nothing but a set of wrapper methods. It is being provided as an alternate, and possibly more efficient, way to construct a ReadOnlyProperties.

    This class inherits the Standard JDK Collection-Framework Class java.util.Properties, and adds a single boolean field named 'built' that, once switched to 'true', will block any subsequent attempts to mutate the underlying data-structure.

    With a Properties having more than, say, 10,000 items, the cost of copying the internal Properties (which is necessary to construct any Read-Only Class) would perhaps be much too high. Instead, by making use of class ROPropertiesBuilder, there is no need to run any kind of internal-data data-copying step at all.

    Simply put all data into the Builder, using any / all standard Java-JDK Properties methods, and when the build() method is invoked, an internal flag is set which will wholly prohibit any further mutation of the data in your builder - thereby allowing the Builder, itself, to be used as the ReadOnlyProperties's internal Data-Structure.
    See Also:
    ReadOnlyProperties, Serialized Form


    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected static long serialVersionUID
      • Fields inherited from class java.util.Properties

        defaults
    • Constructor Summary

      Constructors 
      Constructor Description
      ROPropertiesBuilder()
      Creates an empty ROPropertiesBuilder (property list) with no default values.
      ROPropertiesBuilder​(int initialCapacity)
      Creates an empty ROPropertiesBuilder (property list) with no default values, and with an initial size accommodating the specified number of elements without the need to dynamically resize.
      ROPropertiesBuilder​(Properties defaults)
      Creates an empty ROPropertiesBuilder (property list) with the specified defaults.
    • Method Summary

       
      Convert this Builder into a ReadOnlyProperties instance
      Modifier and Type Method
      ReadOnlyProperties build()
      Simply transfers 'this' instance' internal Properties to the ReadOnlyProperties Wrapper-Class.
       
      Set a Property Value
      Modifier and Type Method
      Object setProperty​(String key, String value)
      Calls the Hashtable method put.
       
      Insert Properties into this Read-Only-Properties Builder
      Modifier and Type Method
      Object put​(Object key, Object value)  
      void putAll​(Map<?,​?> t)  
      Object putIfAbsent​(Object key, Object value)  
       
      Remove Properties from this Read-Only-Properties Builder
      Modifier and Type Method
      void clear()  
      Object remove​(Object key)  
      boolean remove​(Object key, Object value)  
       
      Compute Entries, and then Insert them into this Properties Builder
      Modifier and Type Method
      Object compute​(Object key, BiFunction<Object,​Object,​?> remappingFunction)  
      Object computeIfAbsent​(Object key, Function<Object,​?> mappingFunction)  
      Object computeIfPresent​(Object key, BiFunction<Object,​Object,​?> remappingFunction)  
      Object merge​(Object key, Object value, BiFunction<Object,​Object,​?> remappingFunction)  
       
      Replace Properties
      Modifier and Type Method
      Object replace​(Object key, Object value)  
      boolean replace​(Object key, Object oldValue, Object newValue)  
      void replaceAll​(BiFunction<Object,​Object,​?> function)  
       
      Load this Properties-Builder from Disk or a Stream
      Modifier and Type Method
      void load​(InputStream inStream)
      Reads a property list (key and element pairs) from the input byte stream.
      void load​(Reader reader)
      Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.
      void loadFromXML​(InputStream in)
      Loads all of the properties represented by the XML document on the specified input stream into this properties table.
       
      Mutable / Read-Write View Generators - Return Instances with Unmodifiable-Wrappers
      Modifier and Type Method
      Set<Map.Entry<Object,​Object>> entrySet()
      Restricted-Access Instance
      Set<Object> keySet()
      Restricted-Access Instance
      Collection<Object> values()
      Restricted-Access Instance
       
      Methods: class java.lang.Object
      Modifier and Type Method
      boolean equals​(Object o)
      Compares the specified Object with this Builder for equality, as per the definition in the private and internal field 'properties'.
       
      Methods: interface java.lang.Cloneable
      Modifier and Type Method
      ROPropertiesBuilder clone()
      Clones this instance' of ROPropertiesBuilder.
      • Methods inherited from class java.util.Properties

        contains, containsKey, containsValue, elements, forEach, get, getOrDefault, getProperty, getProperty, hashCode, isEmpty, keys, list, list, propertyNames, rehash, save, size, store, store, storeToXML, storeToXML, storeToXML, stringPropertyNames, toString
      • Methods inherited from class java.lang.Object

        finalize, getClass, notify, notifyAll, wait, wait, wait
    • Field Detail

      • serialVersionUID

        🡇     🗕  🗗  🗖
        protected static final long serialVersionUID
        This fulfils the SerialVersion UID requirement for all classes that implement Java's interface java.io.Serializable. Using the Serializable Implementation offered by java is very easy, and can make saving program state when debugging a lot easier. It can also be used in place of more complicated systems like "hibernate" to store data as well.
        See Also:
        Constant Field Values
        Code:
        Exact Field Declaration Expression:
         protected static final long serialVersionUID = 1;
        
    • Constructor Detail

      • ROPropertiesBuilder

        🡅  🡇     🗕  🗗  🗖
        public ROPropertiesBuilder()
        Creates an empty ROPropertiesBuilder (property list) with no default values.

        The initial capacity of a Properties object created with this constructor is unspecified.
      • ROPropertiesBuilder

        🡅  🡇     🗕  🗗  🗖
        public ROPropertiesBuilder​(int initialCapacity)
        Creates an empty ROPropertiesBuilder (property list) with no default values, and with an initial size accommodating the specified number of elements without the need to dynamically resize.
        Parameters:
        initialCapacity - the Properties will be sized to accommodate this many elements
        Throws:
        java.lang.IllegalArgumentException - if the initial capacity is less than zero.
        Code:
        Exact Constructor Body:
         super(initialCapacity);
        
      • ROPropertiesBuilder

        🡅  🡇     🗕  🗗  🗖
        public ROPropertiesBuilder​(java.util.Properties defaults)
        Creates an empty ROPropertiesBuilder (property list) with the specified defaults.

        The initial capacity of a Properties object created with this constructor is unspecified.
        Parameters:
        defaults - the defaults.
        Code:
        Exact Constructor Body:
         super(defaults);
        
    • Method Detail

      • build

        🡅  🡇     🗕  🗗  🗖
        public ReadOnlyProperties build()
        Simply transfers 'this' instance' internal Properties to the ReadOnlyProperties Wrapper-Class.
        Returns:
        a newly constructed ReadOnlyProperties "Wrapper-Class", shielding the internal 'properties' private-field from any modification.
        Code:
        Exact Method Body:
         this.built = true;
        
         return (size() == 0)
             ? ReadOnlyProperties.emptyROP()
             : new ReadOnlyProperties(this, friendClassBadge);
        
      • setProperty

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object setProperty​(java.lang.String key,
                                            java.lang.String value)
        Calls the Hashtable method put. Provided for parallelism with the getProperty method. Enforces use of String's for property keys and values. The value returned is the result of the Hashtable call to put.
        Overrides:
        setProperty in class java.util.Properties
        Parameters:
        key - the key to be placed into this property list.
        value - the value corresponding to key.
        Returns:
        the previous value of the specified key in this property list, or null if it did not have one.
        See Also:
        Properties.getProperty(java.lang.String)
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.setProperty(key, value);
        
      • load

        🡅  🡇     🗕  🗗  🗖
        public void load​(java.io.Reader reader)
                  throws java.io.IOException
        Reads a property list (key and element pairs) from the input character stream in a simple line-oriented format.

        Properties are processed in terms of lines. There are two kinds of lines, natural lines and logical lines. A natural line is defined as a line of characters that is terminated either by a set of line terminator characters ('\n' or '\r' or '\r\n') or by the end of the stream. A natural line may be either a blank line, a comment line, or hold all or some of a key-element pair. A logical line holds all the data of a key-element pair, which may be spread out across several adjacent natural lines by escaping the line terminator sequence with a backslash character '\'. Note that a comment line cannot be extended in this manner; every natural line that is a comment must have its own comment indicator, as described below. Lines are read from input until the end of the stream is reached.

        A natural line that contains only white space characters is considered blank and is ignored. A comment line has an ASCII '#' or '!' as its first non-whitespace character; comment lines are also ignored and do not encode key-element information. In addition to line terminators, this format considers the characters space (' ', '\u005Cu0020'), tab ('\t', '\u005Cu0009'), and form feed ('\f', '\u005Cu000C') to be white space.

        If a logical line is spread across several natural lines, the backslash escaping the line terminator sequence, the line terminator sequence, and any white space at the start of the following line have no effect on the key or element values. The remainder of the discussion of key and element parsing (when loading) will assume all the characters constituting the key and element appear on a single natural line after line continuation characters have been removed. Note that it is not sufficient to only examine the character preceding a line terminator sequence to decide if the line terminator is escaped; there must be an odd number of contiguous backslashes for the line terminator to be escaped. Since the input is processed from left to right, a non-zero even number of 2n contiguous backslashes before a line terminator (or elsewhere) encodes n backslashes after escape processing.

        The key contains all of the characters in the line starting with the first non-whitespace character and up to, but not including, the first unescaped '=', ':', or white space character other than a line terminator. All of these key termination characters may be included in the key by escaping them with a preceding backslash character; for example,

        \:\=

        would be the two-character key ":=". Line terminator characters can be included using '\r' and '\n' escape sequences. Any white space after the key is skipped; if the first non-whitespace character after the key is '=' or ':', then it is ignored and any white space characters after it are also skipped. All remaining characters on the line become part of the associated element string; if there are no remaining characters, the element is the empty string "". Once the raw character sequences constituting the key and element are identified, escape processing is performed as described above.

        As an example, each of the following three lines specifies the key "Truth" and the associated element value "Beauty":

        • Truth = Beauty
        • Truth: Beauty
        • Truth :Beuty


        As another example, the following three lines specify a single property:

        • fruits      apple, banana, pear, \
                      cantaloupe, watermelon, \
                      kiwi, mango


        The key is "fruits" and the associated element is:
        "apple, banana, pear, cantaloupe, watermelon, kiwi, mango"
        Note that a space appears before each '\' so that a space will appear after each comma in the final result; the '\', line terminator, and leading white space on the continuation line are merely discarded and are not replaced by one or more other characters.

        As a third example, the line:

        • cheeses


        specifies that the key is "cheeses" and the associated element is the empty string "".

        Characters in keys and elements can be represented in escape sequences similar to those used for character and string literals (see The Java Language Specification section 3.3 and 3.10.6 The differences from the character escape sequences and Unicode escapes used for characters and strings are:

        • Octal escapes are not recognized.
        • The character sequence '\b' does not represent a backspace character.
        • The method does not treat a backslash character, '\', before a non-valid escape character as an error; the backslash is silently dropped. For example, in a Java String the sequence "\z" would cause a compile time error. In contrast, this method silently drops the backslash. Therefore, this method treats the two character sequence "\b" as equivalent to the single character 'b'.
        • Escapes are not necessary for single and double quotes; however, by the rule above, single and double quote characters preceded by a backslash still yield single and double quote characters, respectively.
        • Only a single 'u' character is allowed in a Unicode escape sequence.

        The specified stream remains open after this method returns.
        Overrides:
        load in class java.util.Properties
        Parameters:
        reader - the input character stream.
        Throws:
        java.io.IOException - if an error occurred when reading from the input stream.
        java.lang.IllegalArgumentException - if a malformed Unicode escape appears in the input.
        java.lang.NullPointerException - if reader is null.
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.load(reader);
        
      • load

        🡅  🡇     🗕  🗗  🗖
        public void load​(java.io.InputStream inStream)
                  throws java.io.IOException
        Reads a property list (key and element pairs) from the input byte stream. The input stream is in a simple line-oriented format as specified in load(Reader) and is assumed to use the ISO 8859-1 character encoding; that is each byte is one Latin1 character. Characters not in Latin1, and certain special characters, are represented in keys and elements using Unicode escapes as defined in section 3.3 of The Java Language Specification.

        The specified stream remains open after this method returns.
        Overrides:
        load in class java.util.Properties
        Parameters:
        inStream - the input stream.
        Throws:
        java.io.IOException - if an error occurred when reading from the input stream.
        java.lang.IllegalArgumentException - if the input stream contains a malformed Unicode escape sequence.
        java.lang.NullPointerException - if inStream is null.
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.load(inStream);
        
      • loadFromXML

        🡅  🡇     🗕  🗗  🗖
        public void loadFromXML​(java.io.InputStream in)
                         throws java.io.IOException,
                                java.util.InvalidPropertiesFormatException
        Loads all of the properties represented by the XML document on the specified input stream into this properties table.

        The XML document must have the following DOCTYPE declaration:

        HTML Elements:
        <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
        


        Furthermore, the document must satisfy the properties DTD described above.

        An implementation is required to read XML documents that use the "UTF-8" or "UTF-16" encoding. An implementation may support additional encodings.

        The specified stream is closed after this method returns.
        Overrides:
        loadFromXML in class java.util.Properties
        Parameters:
        in - the input stream from which to read the XML document.
        Throws:
        java.io.IOException - if reading from the specified input stream results in an IOException.
        java.io.UnsupportedEncodingException - if the document's encoding declaration can be read and it specifies an encoding that is not supported
        java.util.InvalidPropertiesFormatException - Data on input stream does not constitute a valid XML document with the mandated document type.
        java.lang.NullPointerException - if in is null.
        See Also:
        Properties.storeToXML(OutputStream, String, String), Character Encoding in Entities
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.loadFromXML(in);
        
      • put

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object put​(java.lang.Object key,
                                    java.lang.Object value)
        Specified by:
        put in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        put in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.put(key, value);
        
      • remove

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object remove​(java.lang.Object key)
        Specified by:
        remove in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        remove in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.remove(key);
        
      • putAll

        🡅  🡇     🗕  🗗  🗖
        public void putAll​(java.util.Map<?,​?> t)
        Specified by:
        putAll in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        putAll in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.putAll(t);
        
      • clear

        🡅  🡇     🗕  🗗  🗖
        public void clear()
        Specified by:
        clear in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        clear in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.clear();
        
      • replaceAll

        🡅  🡇     🗕  🗗  🗖
        public void replaceAll​
                    (java.util.function.BiFunction<java.lang.Object,​java.lang.Object,​?> function)
        
        Specified by:
        replaceAll in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        replaceAll in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         super.replaceAll(function);
        
      • putIfAbsent

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object putIfAbsent​(java.lang.Object key,
                                            java.lang.Object value)
        Specified by:
        putIfAbsent in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        putIfAbsent in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.putIfAbsent(key, value);
        
      • remove

        🡅  🡇     🗕  🗗  🗖
        public boolean remove​(java.lang.Object key,
                              java.lang.Object value)
        Specified by:
        remove in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        remove in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.remove(key, value);
        
      • replace

        🡅  🡇     🗕  🗗  🗖
        public boolean replace​(java.lang.Object key,
                               java.lang.Object oldValue,
                               java.lang.Object newValue)
        Specified by:
        replace in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        replace in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.replace(key, oldValue, newValue);
        
      • replace

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object replace​(java.lang.Object key,
                                        java.lang.Object value)
        Specified by:
        replace in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        replace in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.replace(key, value);
        
      • computeIfAbsent

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object computeIfAbsent​
                    (java.lang.Object key,
                     java.util.function.Function<java.lang.Object,​?> mappingFunction)
        
        Specified by:
        computeIfAbsent in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        computeIfAbsent in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.computeIfAbsent(key, mappingFunction);
        
      • computeIfPresent

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object computeIfPresent​
                    (java.lang.Object key,
                     java.util.function.BiFunction<java.lang.Object,​java.lang.Object,​?> remappingFunction)
        
        Specified by:
        computeIfPresent in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        computeIfPresent in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.computeIfPresent(key, remappingFunction);
        
      • compute

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object compute​
                    (java.lang.Object key,
                     java.util.function.BiFunction<java.lang.Object,​java.lang.Object,​?> remappingFunction)
        
        Specified by:
        compute in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        compute in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.compute(key, remappingFunction);
        
      • merge

        🡅  🡇     🗕  🗗  🗖
        public java.lang.Object merge​
                    (java.lang.Object key,
                     java.lang.Object value,
                     java.util.function.BiFunction<java.lang.Object,​java.lang.Object,​?> remappingFunction)
        
        Specified by:
        merge in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        merge in class java.util.Properties
        Code:
        Exact Method Body:
         if (this.built) throw new AttemptedModificationException(ROP);
         return super.merge(key, value, remappingFunction);
        
      • entrySet

        🡅  🡇     🗕  🗗  🗖
        public java.util.Set<java.util.Map.Entry<java.lang.Object,​java.lang.Object>> entrySet
                    ()
        
        Restricts a back-door into the underlying data-structure.

        UnsupportedOperationException Specifics:
        This method invokes the Java Standard Collections class static-method for 'wrapping' this method's returned Set in an Immutable-Wrapper. Java's Collections Framework Immutable-Wrappers have been around since prior to JDK 8, and are easy to use. The wrapper utilized here is needed because this particular method returns a Read-Write "View" into the underlying Properties that facilitates modifying data inside this class' instances.

        Once 'this' builder instance has been built into a Read-Only Data-Structure, this Set (which possesses methods for mutating the Properties) would provide a potential back-door for breaking the Immutable-Contract of the ReadOnlyProperties that is ultimately built.

        Remember that all sub-sets and sub-maps returned by the Java Collections Framework guarantee that any changes to the sub-set or sub-map will be reflected and translated back into the original Collection from whence they were created.

        The returned instance is usable, but any method that would modify this Properties-Builder will, instead, throw a Java UnsupportedOperationException.
        Specified by:
        entrySet in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        entrySet in class java.util.Properties
        Returns:
        a java.util.Set that cannot modify this Properties-Builder
        Code:
        Exact Method Body:
         return Collections.unmodifiableSet(super.entrySet());
        
      • keySet

        🡅  🡇     🗕  🗗  🗖
        public java.util.Set<java.lang.Object> keySet()
        Restricts a back-door into the underlying data-structure.

        UnsupportedOperationException Specifics:
        This method invokes the Java Standard Collections class static-method for 'wrapping' this method's returned Set in an Immutable-Wrapper. Java's Collections Framework Immutable-Wrappers have been around since prior to JDK 8, and are easy to use. The wrapper utilized here is needed because this particular method returns a Read-Write "View" into the underlying Properties that facilitates modifying data inside this class' instances.

        Once 'this' builder instance has been built into a Read-Only Data-Structure, this Set (which possesses methods for mutating the Properties) would provide a potential back-door for breaking the Immutable-Contract of the ReadOnlyProperties that is ultimately built.

        Remember that all sub-sets and sub-maps returned by the Java Collections Framework guarantee that any changes to the sub-set or sub-map will be reflected and translated back into the original Collection from whence they were created.

        The returned instance is usable, but any method that would modify this Properties-Builder will, instead, throw a Java UnsupportedOperationException.
        Specified by:
        keySet in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        keySet in class java.util.Properties
        Returns:
        a java.util.Set that cannot modify this Properties-Builder
        Code:
        Exact Method Body:
         return Collections.unmodifiableSet(super.keySet());
        
      • values

        🡅  🡇     🗕  🗗  🗖
        public java.util.Collection<java.lang.Object> values()
        Restricts a back-door into the underlying data-structure.

        UnsupportedOperationException Specifics:
        This method invokes the Java Standard Collections class static-method for 'wrapping' this method's returned Collection in an Immutable-Wrapper. Java's Collections Framework Immutable-Wrappers have been around since prior to JDK 8, and are easy to use. The wrapper utilized here is needed because this particular method returns a Read-Write "View" into the underlying Properties that facilitates modifying data inside this class' instances.

        Once 'this' builder instance has been built into a Read-Only Data-Structure, this Collection (which possesses methods for mutating the Properties) would provide a potential back-door for breaking the Immutable-Contract of the ReadOnlyProperties that is ultimately built.

        Remember that all sub-sets and sub-maps returned by the Java Collections Framework guarantee that any changes to the sub-set or sub-map will be reflected and translated back into the original Collection from whence they were created.

        The returned instance is usable, but any method that would modify this Properties-Builder will, instead, throw a Java UnsupportedOperationException.
        Specified by:
        values in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        values in class java.util.Properties
        Returns:
        a java.util.Collection that cannot modify this Properties-Builder
        Code:
        Exact Method Body:
         return Collections.unmodifiableCollection(super.values());
        
      • equals

        🡅  🡇     🗕  🗗  🗖
        public boolean equals​(java.lang.Object o)
        Compares the specified Object with this Builder for equality, as per the definition in the private and internal field 'properties'.
        Specified by:
        equals in interface java.util.Map<java.lang.Object,​java.lang.Object>
        Overrides:
        equals in class java.util.Properties
        Parameters:
        o - object to be compared for equality with this ROPropertiesBuilder instance
        Returns:
        true if the specified Object is equal to this Builder
        Code:
        Exact Method Body:
         if (this == o) return true;
         if (! (o instanceof ROPropertiesBuilder)) return false;
         return super.equals((Properties) o);
        
      • clone

        🡅     🗕  🗗  🗖
        public ROPropertiesBuilder clone()
        Clones this instance' of ROPropertiesBuilder.

        The clone that's returned has had it's internal 'built' boolean-flag set FALSE
        Overrides:
        clone in class java.util.Properties
        Returns:
        a clone of this builder
        Code:
        Exact Method Body:
         return new ROPropertiesBuilder(this);