Home‎ > ‎CIS36B‎ > ‎cis-36b-schedule‎ > ‎

transitionlesson

Watch the Lesson 17 Video Here!



Announcements

  • Reminder: Course project due next week!
    • Please upload the following to Canvas:
      • Your presentation (powerpoint or similar)
      • Your code, including all files I would need to run your code
      • Everyone on team submits - make sure you have a copy
  • No Labs this week - work on your course project
  • However, there is a quiz due Friday - don't forget!
  • Midterm 2 Results
    • As: 22 (2 100% scores)
    • Bs: 7
    • Cs: 1
    • Ds: 2
    • Fs: 2
    • No Shows: 0
  • Start practicing for the final now - correct any mistakes you made on midterm 2
    • These questions (very similar) will appear on the final exam!
  • If you have ever wondered what it would be like to interview at Google, what questions might be asked, and the sorts of skills the interviewer is looking for, THIS is your chance to find out.


    Mike Gainer of Google will return and deliver his extremely well received talk about the kinds of technical questions asked on the Google programming interview.  Here are the details.  



    Event:            A Mock Google Interview

    Date / Time:  Tuesday March 10th @ 4:30PM- 5:30PM

    Location:        Back of Computer Lab

    Description:


     There will also be a 30 minute Q & A period after the presentation.






Learning Objectives
By the end of today's class, you should know...
  • Strings and the String pool
  • What is the difference between a StringBuffer, StringBuilder and String?
  • When would you choose to declare a String, StringBuilder and StringBuffer variable?
  • What are some of the common StringBuilder methods?

Lesson 15 and 16 Practice Exam Questions

1. What will be the output of the below program if the user enters "two" for the numInParty?

import java.util.Scanner; 
import java.util.InputMismatchException;

public class TestExceptions {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numInParty = 0;
try {
System.out.print("Welcome to Chez Yum Restaurant!");
System.out.print("Enter the number in your party: ");
numInParty = input.nextInt();
System.out.println("We can seat " + numInParty
+ " people right away!");
} catch(NullPointerException e) {
System.out.println( "Error! String is empty!");
} catch(InputMismatchException e) {
System.out.println("Please enter a number not text!");
} finally {     
System.out.println("Thanks visiting Chez Yum!");
     }
  }
}

 

 2. Update the below method to throw an IndexOutOfBoundsException:

public E get(int index) {
        if (index < 0 || index > numItems) {
            System.out.println("Get error: Index "

                        + index  + " is out of bounds.");

            return null;
        }
        return array[index];
}

Hint: Update both the method signature and the method body!

3. Update the below method to include a try-catch block rather than throwing the exception to the caller method

public static void printFile(String fileName, final int[] array) 
throws IOException {
File file = new File(fileName);
PrintWriter out = new PrintWriter(file);
for (int i = 0; i < array.length; i++) {
out.println(array[i]);
}
out.close();
}


The String Class

  • In CIS 36A, you learned about a class called String that allows the storage of multiple characters as a single piece of data
  • The String class provides many useful methods for working with Strings, including:
    • length(): Returns the length of this string. The length is equal to the number of Unicode code units in the string.
    • charAt(index): Returns the char value at the specified index. An index ranges from 0 to length() - 1. The first char value of the sequence is at index 0, the next at index 1, and so on, as for array indexing.
    • substring(beginIndex, endIndex): Returns a string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1.
    • indexOf(ch): Returns the index within this string of the first occurrence of the specified character. If a character with value ch occurs in the character sequence represented by this String object, then the index (in Unicode code units) of the first such occurrence is returned.
    • replace(oldChar, newChar): Returns a string resulting from replacing all occurrences of oldChar in this string with newChar.
  • As well as overloaded versions of some of the above methods
  • Many of these methods are made possible by the fact that the String class uses a private final char array to store its value:
public final class String {
    private final char value[];
}
  • Therefore, the String class offers the benefits of an array, including its indexing system.

String Immutability

  • The String class is what is known as an immutable class.
    • Once an object of this class has been created, it can never be changed.
  • Immutability is achieved by storing the data in a private and final variable (as shown above)
  • Additionally, none of the String methods alter the contents of this array.
  • Instead, a method like replace, which seemingly alters the String, will return a new String instead of altering the original one.
Why Make String Immutable?
  • String variables are used in a wide variety of applications where security is important, such as database connections, network connections, opening files
  • Were String not immutable, a connection or file name could be changed, leading to a potential security threat.
The String Pool
  • One unique aspect of String's immutability is its use of the "String pool"
  • The String pool is a "pool" of all String constants stored in the heap memory.
  • Each time a new String variable is declared and assigned a value, Java searches the String pool to determine if that value already exists in the String pool.
    • If the value does not yet exist in the String pool, it will be added.
    • If it does exist, the new String variable will store a reference to the location of that existing String.
  • For example:
String pool in the heap


  • In the above example, s1 and s3 are both storing references to the same location in memory (where "Apple" is located)
  • Therefore, we can use == to compare them for equality (true!), as they are both storing a reference to the same object.
  • However, if we want to create a new object, separate from the "Apple" value already stored in the String pool, we can call an alternate String constructor:
String s4 = new String("Apple"); //added to the heap, but not the String pool
  • In this case, s1 != s4
  • Using the new keyword always results in the creating of a new String object.
  • A new String object gets created using the assignment operator (=) or "", only when a matching String object with the same value is not found in the String pool
  • The benefit of the String pool is that it allows the JVM to reuse String objects, and thus increase space efficiency (less memory is used) of programs.

String Pool Example:


class Test {
    public static void main(String[] args){
       
        String one = "hello";
        String two = "hello";
        String three = new String("hello");
        String four = "Hello";
        System.out.println("one == two: " + (one == two));
        System.out.println("one == three: " + (one == three));
        System.out.println("one.equals(three): " + (one.equals(three)));
        System.out.println("one == four: " + (one == four));
        System.out.println("three == \"hello\": " + (three == "hello"));
      
    }
}

Group Activity

  • How many String objects are created in the following program?
class Test {
    public static void main(String[] args){
       
        String a = "Apple";
        String b = "Papaya";
        String c = "Apple";
        String d = "papaya";
        String e = new String("Papaya");
        if (e == "Papaya") {
            System.out.println("Papaya");
        } else {
            System.out.println("Apple");
        }
      
    }
}


The StringBuffer and StringBuilder Classes

  • The StringBuffer and StringBuilder classes are similar to the String class, except that the StringBuffer and StringBuilder classes are mutable, whereas the value of a String object is fixed once it has been created.
StringBuilder is mutable
  • StringBuffer and StringBuilder objects can be used anywhere that a String object is used.
  • However, these two classes are more flexible than String, and, in certain cases, are a more efficient choice.

  • For example, when performing many concatenations (such as inside of a loop), it can be more efficient to use a StringBuffer or StringBuilder object, because these objects will simply update the values of their char arrays, rather than creating a brand new object.
  • Internally, the + operator for the String class has been optimized to use a StringBuilder:
String s1 = "hello";
String s2 = "world";
String concat = s1 + " " + s2;

//will be implicitly converted to the following

StringBuilder s = new StringBuilder();
concat = s.append(s1).append(s2).toString();

  • However, it will return a new StringBuilder object for each statement
    • Therefore, in a situation like a loop, there can be a heavy performance penalty for the creation of so many new objects, as shown in the example below.

String Concatenation Example:

public class Test {

    public static void main(String[] args){  
        long startTime = System.currentTimeMillis();
       
        String java = "Java";
        for (int i=0; i<10000; i++){  
            java = java + " is fun! Java";  
        }  
        System.out.println("Time taken by + operator concatenation: "
            +(System.currentTimeMillis()-startTime)+"ms");  
        startTime = System.currentTimeMillis();  
       
        StringBuilder sb = new StringBuilder("Java");  
        for (int i=0; i<10000; i++){  
            sb.append(" is fun! Java");  
        }    
        System.out.println("Time taken by StringBuilder concatentation: "
            +(System.currentTimeMillis()-startTime)+"ms");  
    }  
}

Example adapted from JavaTPoint

StringBuffer vs StringBuilder

  • Before JDK 5, StringBuffer was the only alternative to the String class.
    • StringBuilder was added to the language in Java 1.5
  • StringBuffer offers synchronization, meaning that it is thread-safe
    • Two threads cannot call methods on the same StringBuffer object simultaneously
  • StringBuilder is, therefore, the more efficient option when synchronization is not required.
    • None of the overhead required to make sure it is thread-safe.



  • Since we are not covering multi-threading in this course, we will focus on StringBuilder rather than StringBuffer.
    • As Oracle states "Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations."

StringBuilder Constructors:

  • There are several ways to construct a new StringBuilder:
public class Test {

    public static void main(String[] args){  
            StringBuilder sb1 = new StringBuilder();
            //constructs an empty StringBuilder with capacity of 16 characters
    
            String s = "Hello";
            StringBuilder sb2 = new StringBuilder(s); 
            //Constructs a StringBuilder with the same contents as s
            System.out.print(sb2);
    }  
}

  • The append method can be used to append data of any type to the end of the StringBuilder object.
  • When appending an object of another class, it will append the toString() representation of that object.
public class Test {

    public static void main(String[] args){ 
            StringBuilder sb1 = new StringBuilder();
           
            String s = "Hello";
            sb1.append(s);
           
            System.out.println(sb1);
           
            StringBuilder sb2 = new StringBuilder("World");
            sb1.append(sb2);
            sb1.append(true);
            sb1.append(2);
            sb1.append('K');
            //append a StringBuilder
            System.out.println(sb1);
    } 
}


  • The insert method will insert data of any type at a specified index in the StringBuilder's character array.
  • When inserting an object of another class, it will insert the toString() representation of that object.

public class Test {

    public static void main(String[] args){  
            StringBuilder sb1 = new StringBuilder("Hello");
            sb1.insert(2, "Mom");
            System.out.println(sb1);
            sb1.insert(5, 55);
            sb1.insert(3,  true);
            System.out.println(sb1);
    }  
}

  • Replaces the characters in a substring (index numbers within the String) of the sequence with characters in the specified String.
public class Test {

    public static void main(String[] args){ 
            StringBuilder sb1 = new StringBuilder("Hello");
            sb1.replace(2,4, "Mom");
            System.out.println(sb1);
    } 
}



CharAt, Length, IndexOf, Substring Methods

  • Just like the String class, StringBuilder also contains these familiar methods:

public class Test {

    public static void main(String[] args){ 
            StringBuilder sb1 = new StringBuilder("Hello");
            System.out.println("Length: " + sb1.length());
            System.out.println("First char: " + sb1.charAt(0));
            System.out.println("IndexOf l: " + sb1.indexOf("l"));
            System.out.println("Substring(0-5): " + sb1.substring(0, 4));
    } 
}

More Information:


Activity 17.1: My Name (10 pts)

  • This activity is adapted from a 36A activity, which you may recognize if you took this course from me.
  • Find a partner for pair programming and open a new Java class named MyName in Eclipse
  • We will create a program to greet the user by name.
  • Add a block comment at the top of your program with your names and section information.
/*
* @author Name of partner 1
* @author Name of partner 2
* CIS 36B, Activity 17.1
*/
  • At the top of the main method, let's declare our first StringBuilder variable - to store the first name of our user:
StringBuilder first_name;
  • Declare a second StringBuilder variable to store the last name of our user in the same _ style.
  • Declare a third StringBuilder variable to store the user's full name:
StringBuilder full_name;

  • Welcome the user with a statement like this one:
System.out.println("Hi! I want to learn your name!\n");
  • Now, prompt the user to enter their first name.
System.out.print("Please enter your first name: ");
  • Follow this prompt with a input.next() statement to capture the user input.
first_name = new StringBuilder(input.next());
  • Now prompt the user to enter his or her last name and store the input in the last_name variable.
  • We want to assign the full_name variable the value of the user's first and last name combined. Let's do so now using concatenation:
full_name = new StringBuilder(first_name.append(last_name));
  • Finally, let's greet the user by his or her full name.
System.out.println("Nice to meet you " + full_name + "!");

  • Run your program to ensure it is giving you the output you expect.
  • Next, let's calculate the length of the user's first and last names and output the result to the console:
System.out.println("The length of your first name is " + first_name.length() + " letters");
  • Now add a similar System.out.println statement to display the length of the user's last name AND full name (remember the full_name variable)
  • Next, let's return the user's initial's to them.
  • Let's declare a new StringBuilder variable called initials that you place at the top of your program with the other variable declarations.
StringBuilder initials = new StringBuilder();

  • Next, we are going to use the charAt() method to extract the initials from the user's first and last names.
  • A person's initials are composed of the first letters of their first and last names.
  • Therefore, we need the letters at position 0 in the first_name and last_name variables.
initials.append(first_name.charAt(???)); //finish this line to add full initials
  • Next, print the results to the console to display for the user.
System.out.println("Your initials are: " + initials);
  • Finally, we will add a title to the name (Mr, Ms or Mx):
  • Prompt the user to enter the preferred title:
      System.out.print("What title do you prefer?\nEnter Mr, Ms or Mx: ");
    String title = input.next();
    if (title.substring(0,2).equalsIgnoreCase("Mr")) {
        full_name.insert(0, "Mr. ");
    }

System.out.println("\nGoodbye, " + full_name + "!");
  • When you are finished, the output of your program should look like below.
  • However, look closely and you will see mistakes in my output.
  • Please correct the mistakes before you turn the program.
  • Submit your MyName.java program to Canvas.
  • Remember that both partners need to submit for full credit.

The output of your program should look like this (except user input will vary):

Hi! I want to learn your name!

Please enter your first name: Jennifer
Please enter your last name: Parrish
Nice to meet you Jennifer Parrish!
The length of your first name is 16 letters
The length of your last name is 7 letters
The length of your full name is 16 letters
Your initials are: JP
What title do you prefer?
Enter Mr, Ms or Mx: Ms

Goodbye, Ms. Jennifer Parrish!

   
Wrap up
  • Answer the questions from today's learning objectives


Upcoming Assignments

  • Course project due next week

Comments