Learn Java for Android Challenge: Strings

What is a String?

At the most fundamental level, Java programs are broken into functionality and data. Much human-readable data comes in the forms of words, characters, punctuation, numbers and so on. Basically, anything the user can type on a keyboard. Programmers call this storage of textual content “string data”, but the data itself can be stored using a variety of different data structures, depending on your requirements:
  • The Java String class (java.lang.String) is a utility class for storing string data that will not be modified.
  • The Java StringBuilder class (java.lang.StringBuilder) is a utility class for storing string data that will be modified; used when concurrency is not an issue.
  • The Java StringBuffer class (java.lang.StringBuffer) is a utility class for storing string data that will be modified; used when concurrency is an issue.
  • An array of char primitives or Character (java.lang.Character) variables
  • An array of byte primitives or Byte (java.lang.Byte) variables
  • Various other data structures and object classes can be used to store string data
As you can see, there are numerous ways to store string data in Java. For example, the following Java variables represent a string of vowel characters in different ways (as bytes, characters, Unicode representations or sub-strings):
 
String strVowels = "aeiou";   
  1. char astrVowels[] = { 'a''e''i''o''u' };   
  • byte abyteVowels[] = { 'a''e''i''o''u' };   
  • byte abyteVowelsU[] = { '\u0061''\u0065','\u0069','\u006F','\u0075' };   
  • String uVowels = new String("\u0061\u0065\u0069\u006F\u0075");   
  • CharSequence csVowels = (CharSequence) new String("aeiou");   
  • StringBuffer sbVowels = new StringBuffer("a" + "e" + "iou");   
  • StringBuilder sVowelBuilder = new StringBuilder();   
  • sVowelBuilder.append('a');   
  • sVowelBuilder.append("eio");   
  • sVowelBuilder.append('\u0075');  
  • The String class is the convenience class used most often, especially by beginners. You’ll also want to have a passing understanding of the CharSequence (java.lang.CharSequence) interface, as it is often used when working with Android resources.

    Working with the String Class

    The String class is available as part of the java.lang package, which is included within the Android SDK for developers to use. The complete documentation for the String class can be found with the Android SDK documentation.
    The String class represents an immutable (unchangeable) sequence of Unicode (16-bit encoding) characters, appropriate for storing characters in any language (English, German, Japanese, and so on).
    So what does this have to do with Android development? Well, strings are used to store content displayed on application screens, or to store the input taken in from a user. Android developers are constantly loading, creating, and manipulating string data. So let’s look at some of the stuff we can do with the String class.

    Creating Strings

    The String class has numerous constructors, for creating and instantiating string variables. String variables can be set to empty using the null keyword. You can also set its content from byte, character, or other String data. For example, here are some ways to create String variables for use within your applications (some are initialized from the variables, like uVowels and sVowelBuilder, defined earlier in this tutorial):
     
    String strVowels1 = "aeiou";   
    1. String strVowels2 = new String("aeiou");   
  • String strVowels3 = new String(sVowelBuilder);   
  • String strVowels4 = new String(sbVowels);   
  • String strVowels5 = new String(uVowels);   
  • String strVowels6 = new String(abyteVowels2);   
  • String strVowels7 = new String(abyteVowelsU);   
  • String strVowels8 = new String("a" + "e" + "iou");   
  • String strVowels9 = new String( new char[]{'\u0061',    
  •                                                      '\u0065','\u0069','\u006F','\u0075'});   
  • String strVowels10 = new String(new byte[]{ '\u0061',   
  •                                                      '\u0065','\u0069','\u006F','\u0075' });  
  • Using Android String Resources

    You can also load strings from Android application resources, provided you have stored them correctly. For example, you can load the string resource for the application name into a String variable as follows:
    1. String strAppName = getResources().getString(R.string.app_name);  
    This requires that the Android application in question contains a string resource named app_name somewhere in the /res/values project directory hierarchy. For example, a file called /res/values/strings.xml which contains the following XML string definition:
    <?xml version="1.0" encoding="utf-8"?>  
    1. <resources>  
  •     <string name="app_name">My Android App Name!</string>  
  • </resources>  
  • Simple String Iteration

    Now let’s look at some of the cool stuff you can do to String objects. First, let’s focus on the features available within the String class itself.
    It’s helpful to think of a String as a sequence of characters. As such, you sometimes want to iterate through its contents, one character at a time. There are numerous ways to do this, but one simple way is to use a for() loop. You can take advantage of the String’s length() method to determine how many characters you’ve got, and the charAt() method to retrieve a specific character by its index, much like you would an array index. For example:

    1. String strVowels = "AEIOU";   
    2. for (int i = 0; i < strVowels.length(); i++) {   
  •     char curChar = strVowels.charAt(i);   
  • }  
  • String Modifications: The Basics

    As mentioned earlier, String variables are immutable, or unchangeable. That is not to say you cannot manipulate the textual contents of a String variable, but each method that does so returns a new String variable. Some common examples of String class methods that generate new String variables include:
    • The concat() method is used to concatenate, or combine, two strings into a new String object. Note: You can also use the + operator to create a new String object from parts as well.
    • The format() method allows you to create parameterized string templates (a more advanced topic for future discussion)
    • The replace() and replaceFirst() methods are used to replace one character or substring with another substring. The replaceAll() method supports regular expression pattern matching.
    • The split() method is helpful for breaking a larger String into numerous substrings. For example, you could break up a comma-delimited list into an array of String objects, one for each list item.
    • The substring() method is used to extract only part of the original String object.
    • The toUpperCase() and toLowerCase() methods are used to change the String’s case, especially useful for normalizing strings.
    • The trim() method is used to hack off (remove) any whitespace before or after the String contents.
    Keep in mind that each of these methods allocates a new String object instance to store the result. The original String variable remains unchanged.

    String Modifications: Converting to Upper and Lowercase

    Sometimes you want to convert your string to uppercase or lowercase. One reason you might want to change the case of a string is to normalize the string to make case-insensitive searching or matching easier to implement.
    1. String strUpperCaseVersion = strVowels.toUpperCase();   
    2. String strLowerCaseVersion = strVowels.toLowerCase();  
    Note that here you have created two new String variables for use. The original String variable, strVowels, remains unchanged.

    String Modifications: Splitting

    Sometimes you want to quickly parse a string into substrings. You might do this to extract the individual words from a sentence, or a delimited list of tags, etc. You can use simple regular expressions with the split() function for this purpose. For example, the following code extracts the individual words (colors) from a String:
     
    String someWords = "Red Orange Yellow Green Blue Indigo";   
    1. String aColors[] = someWords.split(" ");  
    If you were to print out the contents of the String array called aColors, you would see that:
     
    aColors[0]=Red   
    1. aColors[1]=Orange   
  • aColors[2]=Yellow   
  • aColors[3]=Green   
  • aColors[4]=Blue   
  • aColors[5]=Indigo  
  • Note that here you have created a new array containing 6 new String variables for use.

    Simple String Matching

    You can check if two strings match using the String class’s compareTo() method. This method will return 0 if, and only if, the two strings are identical:
     
    String strVowels = "AEIOU";   
    1. if(strVowels.compareTo("AEIOU") == 0)   
  • {   
  •     // Strings match! (This code will execute)   
  • else {   
  •     // Strings don’t match!   
  • }  
  • Note that the compareTo() method is case-sensitive. Consider converting both sides of your comparison to one case before comparing them, unless you are specifically looking for one case. If you don’t care about case, you can also use the compareToIgnoreCase() method instead of the compareTo() method:
     
    String strVowels = "AEIOU";   
    1. if(strVowels.compareToIgnoreCase ("aeiou")== 0)   
  • {   
  •     // Strings match! (This code will execute)   
  • else {   
  •     // Strings don’t match!   
  • }  
  • Simple String Searching

    Sometimes you want to search a string for a character or substring. There are many other ways to perform string matching and searching, allowing you to build whatever search methods you desire. You can also hunt for specific characters or substrings using the indexOf() and lastIndexOf() methods, check if a string begins or ends with a substring using the startsWith() and endsWith() methods. Finally, the matches() method supports regular expression matching.
    Here we use the contains() method to determine if a specific substring exists:
     
    if(strVowels.contains("IOU")==true)   
    1. {   
    2.     // String contains IOU sub-string!   
  • }  
  • If you don’t care about case, use the compareToIgnoreCase() method instead:
     
    String strVowels = "AEIOU";        
    1. if(strVowels. compareToIgnoreCase ("aeiou")== 0)   
  • {   
  •     // Strings match! (This code will execute)   
  • else {   
  •     // Strings don’t match!   
  • }  
  • TIP: When implementing matching and searching functionality in your applications, don’t forget to do any preprocessing string manipulation necessary to rule out upper/lower/mixed case string issues before searching. User input normalization can be done as part of the input validation process, keeping your code as simple and maintainable as possible.

    Strings and Other Data Types

    The String object is so fundamental to Java that every class, due to being derived from the root class called Object (java.lang.Object), has a toString() method to create a useful string representation of their value. Classes that don't have a reasonable string representation usually return some identifier or debug information as to the type of class. Those that do have a reasonable string representation, such as a number string from an Integer object, return the textual representation of the encapsulated number. When concatenated with a String, such as with the plus (+) operator described above, the toString() method results are used by default. For example:
     
    Integer iNum = new Integer(123);   
    1. String sText = "The number one-two-three = ";   
  • String sFullText = sText + iNum;   
  • String sFullText2 = sText + iNum.toString();  
  • Both the strings (sFullText and sFullText2) have the same value, "The number one-two-three = 123". Many such objects can also work in reverse. That is, they can parse a String representation and convert it to the native type the object is representing. For instace, again with the Integer class, the parseInt() method can be used to get a new Integer object based on the string representation.

    Strings and Performance

    As you’ve seen, strings can be used to great effect. String creation and manipulation does, however, have some drawbacks. Imprudent String manipulation can have negative performance implications for your application. It’s a basic design principle of Java to not create objects you don’t need. You can see that string manipulation and modifications can result in a lot of String variables floating around. Here are some tips for good string usage:
    • Don’t create String variables you don’t need, especially temporary ones.
    • Use the StringBuilder and StringBuffer classes to generate string contents from the ground up.
    • Review the performance suggestions available on the Android Developer website.
    • Use static final String constants for String values known at compile time.

    Wrapping Up

    Strings are an important data type that Android developers use to store textual data. String data, whether it be a sequence of characters, numbers, symbols, or some mix thereof, can be stored in a variety of ways, but the String class is the primary utility class used for this purpose. The String class, and it’s helper classes like StringBuilder, contain a robust set of methods for use with strings, allow their contents to be searched or modified.

    Comments

    Popular posts from this blog

    Android Objective type Question and Answers

    Android Questions and Answers for written exams