Please send questions to st10@humboldt.edu .

/**
 * PlayWithStrings - a class where just a few of the lovely Java
 *                   String class capabilities are demonstrated...
 *                   (for more, go the the Java 1.4 API, package
 *                   java.lang, class String)
 *                   
 * @author Sharon M. Tuttle
 * @version 3-13-03 (pre-lab)
 */

// I'd like to use demonstrative println's, expected's, actual's from
// Java Power Tools... so I'll extend JPFalt, like I do for testing
// classes
public class PlayWithStrings extends JPFalt
{
    public static void main(String[] args) 
    { 
            new PlayWithStrings(); 
    }

    /**
     * stringPlay
     * Purpose: play around with some of the capabilities of
     *          Java's String class (and perhaps uncover a
     *          few Deep Java Truths (tm) along the way...)         
     */
    public void stringPlay()
    {
        // you already know how to declare and instantiate
        // instances of String objects...
        String name = "Ann";
        
        // this DOES work, too;
        String anotherName = new String("Anne");
        
        testHeader("stringPlay");
        expected("Ann");
        actual(name);
        expected("Anne");
        actual(anotherName);
        
        // so, now THAT's out of the way...
        
        // String's have a wide array of available methods ---
        // for more, see the Java 1.4 API, where class String
        // is referenced under Java package java.lang
        // (remember that link from the course web page
        // to the Java 1.4 API!)
        
        // for example: what if you want to know how *long* a
        // String is (how many characters)?
        //
        // method length() will tell you that, for a String
        // object (it IS a method, remember those ()'s!)
        println("\ntrying out String length() method:");
        expected(3);
        actual(name.length());
        expected(4);
        actual(anotherName.length());
        expected(0);
        actual(("").length());   // I can call a String method for a
                                 // String literal...! 8-)
                                 
        // Okay --- can I pull out a character at a given position
        // within a string?
        //
        // method charAt(int pos) will return the character at
        // position pos in the String (where 0 is the position of
        // the first character, etc.
        // (NOTE: it returns a primitive char type instance)
        println("\ntrying out String charAt() method:");
        expected('A');
        actual(name.charAt(0));
        expected('n');
        actual(name.charAt(1));
        expected('n');
        actual(name.charAt(2));
        
        // what happens if the position ISN'T in the String?
        expected("Exception will be thrown:");
        //actual(name.charAt(3));
        
        // ...and, now that we know it'll throw an Exception,
        // let's check out its type:
        try
        { 
            name.charAt(3);
        }
        catch(Exception ex)
        {
            actual("Exception thrown: " + ex);
        }
        
        // ASIDE #1: could I use this to put the characters
        // of a String into a List or a Stack?
        //
        // NO --- char's are primitive, not Objects!
        //
        // hey --- but so are int's and double's, etc., and
        // THEY have a wrapper class to make object versions of
        // them. Do char's?
        //
        // YES --- Character
        println("\ntrying out wrapper class Character for char");
        Cs132Stack myStack = new Cs132LinkedStack();
                
        // this fails:
        //for (int i=0; i < name.length(); i++)
        //{
        //    myStack.push(name.charAt(i));
        //}
        
        // this works:
        for (int i=0; i < name.length(); i++)
        {
            myStack.push(new Character(name.charAt(i)));
        }
        
        expected("Stack contains n, n, A");
        actual(myStack);
        
        // Back to Strings, now -- how can I see if 2 String
        // instances are equal?
        // 
        // TRICK QUESTION! What do I *mean* by equal?
        // Does "equal" mean they reference the same physical String?
        // Does "equal" mean they contain the same characters,
        //     but they may not be a reference to the same
        //     physical String?
        // It matters!
        println("\n== for Objects such as Strings...");
        anotherName = "Ann" + "ie";    
                                // anotherName references a new String
                                // object referencing "Annie"
        name = name + "ie";
        String a3rdName = name; // a3rdName references the same
                                // thing that name does
                                
        println("name contains:        " + name);
        println("anotherName contains: " + anotherName);
        println("a3rdName contains:    " + a3rdName);
        println("(name == anotherName) returns: " + (name == anotherName));
        println("(name == a3rdName) returns:    " + (name == a3rdName));
        
        // can you see why (name == anotherName) returns false?
        // ...because == means, are they the SAME Object instance
        // in memory?
        
        // HOW, then, can we check for equivalent CONTENTS?
        // 
        // method equals() --- which, by the way, is included
        // in LOTS of Object classes, for this very reason!
        println("(name.equals(anotherName) returns: " +
                                           (name.equals(anotherName)));
        println("(name.equals(a3rdName)) returns  : " +
                                           (name.equals(a3rdName)));
                                           
        // ASIDE #2: this equals() method works for a LOT of
        // Java objects! (And you can consider including it
        // for object classes you create, too...)
        //
        // ALSO: it means you need to be CAREFUL comparing instances
        // of the wrapper classes! Probably need to use equals(),
        // most of the time...
        println("\nusing equals() for other objects...");
        int num1 = 5;
        int num2 = 4;
        num2++;
        Integer objNum1 = new Integer(num1);
        Integer objNum2 = new Integer(num2);
        println("(objNum1 == objNum2) returns:      " + 
                                     (objNum1 == objNum2));
        println("(objNum1.equals(objNum2)) returns: " +
                                     (objNum1.equals(objNum2)));
                                     
        char char1 = 'a';
        char char2 = 'a';
        Character objChar1 = new Character(char1);
        Character objChar2 = new Character(char2);
        println("(objChar1 == objChar2) returns:      " +
                                     (objChar1 == objChar2));
        println("(objChar1.equals(objChar2)) returns: " +
                                     (objChar1.equals(objChar2)));
       
       // nice touch: String can let you do a CASE-INSENSITIVE
       // comparison, too:
       //
       // equalsIgnoreCase()
       println("\nplaying with String method equalsIgnoreCase():");
       name = "Ann";
       String name2 = "ann";
       String name3 = "Ann "; // note the BLANK on the end...!
       println("name:  <" + name + ">");
       println("name2: <" + name2 + ">");
       println("name3: <" + name3 + ">");
       println("(name.equals(name2)) returns: " + 
                                     (name.equals(name2)));
       println("(name.equalsIgnoreCase(name2)) returns: " +
                                     (name.equalsIgnoreCase(name2)));
       println("(name.equalsIgnoreCase(name3)) returns: " +
                                     (name.equalsIgnoreCase(name3)));
                                     
       // AND: there are many more!
       // a FEW examples (with argument types NOT included, note!!!)
       //    compareTo() - (yes, String implements the Comparable interface)
       //    compareToIgnoreCase()
       //    indexOf() - find the 1st instance of a given char in a String
       //    substring() - ways to grab substrings from a String
       //    replace() - ways to replace a given char with another given
       //                char
       //    toLowerCase() - convert to lower case
       //    toUpperCase() - convert to upper case
       //    ...and more!
       //    
    }
    
    /**
     * quickAndSleazyBlueJInput
     * Purpose: play with simple "user" input we can get away with within
     *          BlueJ --- yes it IS quick-and-sleazy...
     *          (we'll get more "formal" later, probably!)
     */
    public void quickAndSleazyBlueJInput(String name1, String name2)
    {
        println("\npointing out quick-n-sleazy BlueJ \"user\" input");
        // Say that you write a method --- such as this --- with
        // parameters. 
        
        // this method will appear as one of the methods for
        // an instantiated BlueJ object --- and when you choose
        // that method, you'll get a little GUI window prompting
        // you for arguments for the parameters.
        
        // it's sleazy, but it should get us through HW #6...
        println("name1 is: " + name1);
        println("name2 is: " + name2);
        println("(name1 == name2) returns:              " + 
                                      (name1 == name2));
        println("(name1.equals(name2) returns:          " +
                                      (name1.equals(name2)));
        println("name1.equalsIgnoreCase(name2) returns: " +
                                      (name1.equalsIgnoreCase(name2)));
    }
}