Class RetN

    • Method Summary

       
      Convenience Getters for SubClasses
      Modifier and Type Method
      Object get​(int i)
      <T> T get​(int i, Class<T> c)
      <T> T GET​(int i)
       
      Convert Fields to Object Array
      Modifier and Type Method
      Object[] asArray()
       
      Retrieve Number of Fields in this Class
      Modifier and Type Method
      abstract int n()
       
      Methods: class java.lang.Object
      Modifier and Type Method
      boolean equals​(RetN other)
      int hashCode()
      String toString()
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, notify, notifyAll, wait, wait, wait
    • Method Detail

      • n

        🡇    
        public abstract int n()
        All implementations of this abstract can indicate which of the RetN instances they are, by returning the number of fields they hold using this method.
        Returns:
        The number of fields contained by the class that is implementing 'this' instance of RetN. So for example, an instance of Ret5 would produce '5', if this method were called; and Ret3 would produce '3', and so on and so forth.
      • asArray

        🡅  🡇    
        public final java.lang.Object[] asArray()
        Retrieve the contents of the instance-descendant class, as an array.
        Returns:
        Returns the instance fields 'a', 'b', 'c' ... of the class that has extended this class as an Object[] array.
        Code:
        Exact Method Body:
         // All classes that inherit RetN implement the 'asArrayInternal()' method.
         // This method simply places the 'a', 'b', 'c' etc... fields into an Object[] array.
         if (this.objArr == null) this.objArr = asArrayInternal();
        
         return this.objArr;
        
      • get

        🡅  🡇    
        public final java.lang.Object get​(int i)
        This will return an instance of Object which represents the ith instance-field from whatever RetN implementation this has been invoked.

        If the implementing class were Ret5, and '3' were passed to parameter 'i', then the value in Ret5.c would be returned.

        If a call to 'get' is made from Ret2, and '3' were passed to 'i', an IndexOutOfBoundsException is thrown.

        NOTE: This can make for easier typing if using the super-class RetN in place of the actual multiple return-value classes themselves. However, remember, if RetN is used instead of the actual abstract-implementation ('Ret5', for instance) you will need cast the fields that you wish to use, eventually!

        Example:
        // This line makes for longer typing, but DOES NOT REQUIRE A CAST TO RETRIEVE FIELDS.
        Ret5<String, String, Integer, String[], Integer> r5 = some_function_returns5();
        String neededStrField = r5.c;
        
        // If the Ret5 super-class RetN is used instead, YOU HAVE TO CAST THE FIELDS TO RETRIEVE THEM
        // The above two lines of code may be replaced by:
        RetN rn = some_function_returns5();
        String neededStrField = rn.get(3, String.class);  // Passing '3' gets field Ret5.c
        
        // **OR**
        @SuppressWarnings("unchecked")
        String neededStrField = (String) rn.get(3);
        
        Parameters:
        i - This specifies which field of the implementing RetN is being requested.

        IMPORTANT: Unlike a Java array, when a '1' is passed to this parameter, it is requesting the first field in the RetN. Passing a value of '0' shall cause an IndexOutOfBoundsException throw.
        Returns:
        This returns the ith field of this class.
        Throws:
        java.lang.IndexOutOfBoundsException - if 'i' is zero or negative, or greater than the value of 'N' for whichever RetN class is being used. If 'this' is an instance of Ret5, then a value of 6 or greater will cause this exception to throw.
        See Also:
        asArray(), get(int, Class), GET(int)
        Code:
        Exact Method Body:
         Object[] objArr = asArray();
        
         if (i < 1) throw new IndexOutOfBoundsException(
             "You have passed " + i + " to parameter i.  This number must be " +
             ((objArr.length > 1)
                 ? ("between 1 and " + objArr.length)
                 : "must be exactly 1.")
         );
        
         else if (i > objArr.length) throw new IndexOutOfBoundsException(
             "You have requested the " + StringParse.ordinalIndicator(i) + " field of " +
             "this class instance-fields, but unfortunately there " + 
             ((objArr.length > 1)
                 ? ("are only " + objArr.length + " fields.")
                 : ("is only 1 field.")
             )
         );
        
         return objArr[i-1]; // minus one, arrays start at index 0.
        
      • get

        🡅  🡇    
        public final <T> T get​(int i,
                               java.lang.Class<T> c)
        This provides a quick way to cast the field to the requested class. This may be quicker typing than using an actual cast, because it will not generate a compiler warning about unchecked casts. If the cast fails, it will throw the usual ClassCastException.
        Parameters:
        i - This specifies which field of the implementing RetN is being requested.

        IMPORTANT: Unlike a Java array, when a '1' is passed to this parameter, it is requesting the first field in the RetN. Passing a value of '0' shall case an IndexOutOfBoundsException exception.
        Returns:
        This returns the ith field of this class.
        Throws:
        java.lang.IndexOutOfBoundsException - if 'i' is zero or negative, or greater than the value of 'N' for whichever RetN class is being used. If 'this' is an instance of Ret5, then a value of 6 or greater will cause this exception to throw.
        java.lang.ClassCastException - If the field cannot be cast to the class provided.
        See Also:
        get(int), GET(int)
        Code:
        Exact Method Body:
         return c.cast(get(i));
        
      • GET

        🡅  🡇    
        public final <T> T GET​(int i)
        This is more magic with Java's Type-Inferencing being applied to a Generic-Cast. Note that this method works a lot like (but not identical to) the later Java 'var' syntax. Here, Java's Type-Inference Mechanism (inside the compile-time, not run-time, logic) will cast the result of this method to whatever type is on the left hand-side of the assignment.

        NOTE: The Java Compiler will output a Compile-Time Error if it appears that it cannot infer type-parameter 'T'.

        ALSO: This method will throw a Run-Time Exception if the cast fails (a 'ClassCastException')
        Type Parameters:
        T - This Type-Parameter is inferred by whatever assignment is taking place, or however the result of this method is being applied, programatically. More can be read about Java's Compile-Time Type-Inferencing Mechanism on the Oracle Website.
        Parameters:
        i - This specifies which field of the implementing RetN is being requested.

        IMPORTANT: Unlike a Java array, when a '1' is passed to this parameter, it is requesting the first field in the RetN. Passing a value of '0' shall case an IndexOutOfBoundsException exception.
        Returns:
        This returns the ith field of this class.
        Throws:
        java.lang.IndexOutOfBoundsException - if 'i' is zero or negative, or greater than the value of 'N' for whichever RetN class is being used. If 'this' is an instance of Ret5, then a value of 6 or greater will cause this exception to throw.
        java.lang.ClassCastException - If the ith field of this class cannot be cast to the type that is inferred for Type-Parameter 'T'.
        Code:
        Exact Method Body:
         return (T) get(i);
        
      • equals

        🡅  🡇    
        public boolean equals​(RetN other)
        Compares 'this' with another instance of RetN.
        Parameters:
        other - Another instance of Ret8.
        Returns:
        If 'this' instance of Ret8 is equal to the 'other' instance of Ret8.
        Code:
        Exact Method Body:
         if (this == other) return true;
        
         Object[] theseFields = asArray();
         Object[] thoseFields = other.asArray();
        
         // This should never happen, because the RetN that calls this only accepts a RetN
         // of the same type.  Leave this here, anyway, you will forget that, and try to type
         // this again.
         if (theseFields.length != thoseFields.length) return false;
        
         for (int i=0; i < theseFields.length; i++)
        
             if (theseFields[i] == thoseFields[i])
                 continue;
        
             else if (
                         ((theseFields[i] != null) && (thoseFields[i] != null))
                         &&
                         (theseFields[i].getClass() == thoseFields[i].getClass())
                         &&
                         theseFields[i].equals(thoseFields[i])
                     )
                 continue;
        
             else
                 return false;
        
         return true;
        
      • hashCode

        🡅  🡇    
        public int hashCode()
        Builds a hash-code to fulfill Java's java.lang.Object requirement. This variant of a hash function simply computes a hashcode for the first two non-null fields of this instance, and returns their sum.

        If there aren't at least two non-null fields in this RetN instance, then the hashcode for however many have been computed (READ: either 0, or 1) is returned.
        Overrides:
        hashCode in class java.lang.Object
        Returns:
        a hash-code that may be used for sets and maps like java.util.Hashtable and java.util.HashSet.
        Code:
        Exact Method Body:
         // This is the value returned.
         int hashCode    = 0;
         int count       = 0;
        
         for (Object field : asArray())
        
             if (field != null)
             {
                 hashCode += field.hashCode();
        
                 // Once two Hash Code's have been computed return the 'SUM' of them.
                 if (++count == 2) return hashCode;
             }
        
         return hashCode;
        
      • toString

        🡅    
        public java.lang.String toString()
        Converts this instance of the implementing RetN to a String.
        Overrides:
        toString in class java.lang.Object
        Returns:
        This instance-object as a String.
        Code:
        Exact Method Body:
         // When a field is set to null, it is more difficult to retrieve the type/class of that
         // field.  The class is printed as part of the output of the 'toString' method.  It does
         // make the string look nicer, and likely will help the user.
         //
         // NOTE: If none of the fields in whatever instance 'this' is a instance of, then variable
         //       'thisClass' is never actually used.
        
         Class thisClass = this.getClass();
        
         // All RetN implementations return their fields as an array.  This array is only created
         // once (in a transietn field), defined above.
         Object[] fields = asArray();
        
         // whatever 'RetN' implentation this instance is, this is actually just the value of 'N'
         int n = n();
        
         // Tells the output-printing mechanism when/if one of the fields is an array.
         boolean[] isArray = new boolean[n];
        
         // These will hold the "Simple Name's" of each class/type in the previous array.
         String[] types = new String[n];
        
         // The fields are named 'a ... e', unless N is 6, 7, or 8.  In that case the fields are
         // named 'a1 ... h8'
        
         String[] FIELD_NAMES = (n < 6) ? fieldNames2To5 : fieldNames6To8;
        
         // This will hold the returned java.lang.String that is provided by this method call.
         StringBuilder sb = new StringBuilder();
        
         // Simple Loop Variables
         int i=0, maxLen=0;
        
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // Loop merely retrieves the TYPE/CLASS of each field as a STRING (and if it is an array)
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         for (Object field : fields)
         {
             // If the field is non-null, retrieving the class is easy, otherwise, it isn't-possible
             // because of GENERIC-ERASURE
        
             if (field != null)
             {
                 Class c     = field.getClass();
                 types[i]    = c.getSimpleName();
                 isArray[i]  = c.isArray();
             }
             else
             {
                 types[i]    = "<GENERIC-ERASURE>";  // Smoke 'em if you got 'em
                 isArray[i]  = false;                // DUMMY-VALUE
             }
        
        
             // These String's are pretty-printed with right-space-pad.  This computes the padding.
             if (types[i].length() > maxLen) maxLen = types[i].length();
        
             i++;
         }
        
         // Formatting: the '+2' adds two space-characters to the output.  These spaces occur
         // *AFTER* the Type/Class is printed to the output.
        
         maxLen += 2;
        
         i=0;
         for (Object field : fields)
         {
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
             // This print's the NAME & TYPE of the Field - For Example: "Ret6.a1: String"
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
             String line = 
                 "Ret" + n + "." + FIELD_NAMES[i] + ":  " +
                 StringParse.rightSpacePad(types[i], maxLen);
        
             sb.append(line);
        
        
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
             // This simply prints the VALUE of the Field.  For arrays, "extra-care is provided"
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
             if (field != null)
             {
                 String s = isArray[i]
                     ? toArrayString(field, types[i])
                     : field.toString();
        
                 if (s.indexOf('\n') != -1)
                     sb.append('\n' + StrIndent.indent(s, 4));
                 else if (line.length() + s.length() > 70)
                     sb.append('\n' + StrIndent.indent(s, 4));
                 else
                     sb.append(s);
             }
             else
                 sb.append("null");
        
             sb.append('\n');
             i++;
         }
        
         return sb.toString();