S-111
  • Home
  • Lectures
  • Problem Sets
  • Sections
  • Syllabus
  • Schedule
  • Staff
  • Resources
  • Canvas
  • Ed Discussion
  • Gradescope

Section 5

  • Review exercises
    • Return of the juice
    • Objects and classes
  • Java exercises

Review exercises

Return of the juice

  1. Given the following confusing program, trace its execution and provide the output. Recall from today’s lecture that, for a variable myString containing a string, the expression myString.length() evaluates to the number of characters in the string. Use VSCode to check your answer. 1
    public class CrazyJuice {
        public static void main(String[] args) {
            String orange = "apple";
            String apple = "yum";
            String grape = "juice";
            String prune = "orange";
            String juice = "grape";
            String yum = "prune";
    
            fresh(apple, juice, orange);
            juice = tasty("grape", prune);
    
            System.out.println(juice + ", thanks!");
    
            fresh(grape, prune, yum);
            tasty(apple, orange);
    
            System.out.println(apple + ", thanks!");
    
            fresh(juice, "apple", apple);
            grape = tasty(apple, yum);
    
            System.out.println(grape + ", thanks!");
    
            fresh(yum, grape, orange);
        }
    
        public static void fresh(String juice, String orange, String tasty) {
            System.out.println("tasty " + orange + " juice, or " +
                               tasty + " and " + juice + "?");
        }
    
        public static String tasty(String orange, String apple) {
            if (orange.length() > apple.length()) {
                return orange;
            } else {
                return apple;
            }
        }
    }
    

Objects and classes

The int and double types are known as primitive types, because the contents of those variables are a fixed number of binary digits that are used to store a value. However, the String type is an example of a reference type, and it “stores” an object (we will soon learn that a variable with a reference type does not actually store the object, but it rather references the object). Objects are compound data types in the sense that they can keep both data (known as fields) and a set of operations or manipulations (the object’s methods).

In order to call a method inside an object the dot (.) operator is used to access the method by name.

We will learn more about making our own objects later in the course, but to start we will focus on String objects, which we can easily construct by creating string literals in our code, as we have been doing.

Consider the following code fragment:

String str1 = "Harvard University";
String str2 = "Professor Sullivan";
  1. Use the substring() method to produce an expression that evaluates to "Harvard". 2
  2. Use the length() methods of each string to produce an expression that evaluates to the sum of the number of characters in both strings. 3
  3. Use the toUpperCase() method of str2 to produce an expression that evaluates to "PROFESSOR SULLIVAN". 4
  4. Write an expression that evaluates to "PROFESSOR". 5
  5. Write an expression using str1 or str2 that evaluates to 'a'. 6
  6. Write an expression using str1 or str2 that evaluates to 'o'. 7
  7. Write an expression that returns the character at index 3 of the string str1. 8

Java exercises

  1. Write a method named countA() that accepts a string as a parameter and returns the integer number of times the character 'a' appears in the string. For example, countA("Harvard") should return 2. 9

  2. Write a method named count() that accepts a string and a char and returns the integer number of times the char appears in the string. For example, count("Professor", 's') should return 2. 10

  3. Write a method named printReverse() that accepts a string as a parameter and prints the string in reverse order. For example, printReverse("tasty apple juice") should produce the following output: 11

    eciuj elppa ytsat
    
  4. Write a method spaced() that takes a string as a parameter and prints each letter of the string with one space between each character. For example, spaced("ALLONS-Y") should produce the following output: 12

    A L L O N S - Y
    
  5. Write a method padString() that takes a string str and an integer maxLength and prints the string with padding on the left, such that the total number of printed characters is exactly maxLength. If the string’s length is greater than or equal to maxLength, your method should print just the string. For example, padString("Monday", 20) should produce the following output: 13

                  Monday
    
  6. Write a method printChant() that takes a string str and an integer count as parameters and prints the string count times, all on the same line. However, an exclamation mark and a space should be added to the end of str so that it looks like a chant. For example, printChant("Go Crimson", 3) produces the following output: 14

    Go Crimson! Go Crimson! Go Crimson!
    
  7. Write a method getChant() that takes a string str and an integer count as parameters and returns a new string that is the concatenation of str with itself, count times. As in printChant(), each occurrence of str should be followed by an exclamation mark and a space. Hint: you will need a loop and a String variable declared outside the loop. For example, getChant("Test, body, update", 2) evaluates to "Test, body, update! Test, body, update! ". 15

  8. Write a method dechant() that takes a string str that has been created using getChant() and returns the un-chanted version. For example, dechant("Hip hip! Hip hip! ") should evaluate to "Hip hip". Hint: you will need to use the fact that any string returned by a call to getChant() will have an exclamation mark in it. You can assume that any exclamation marks in str were the result of an original call to getChant(). 16

  9. Write a method shift() that takes a string str and an integer offset and returns a new string where the letters of str are shifted ahead by offset spaces in the string. For example, the expression shift("Sullivan", 3) should evaluate to "vanSulli". Before starting, think about what methods of a String object you can use. For an extra challenge, try to make your method able to accept a shift of any positive amount. 17


  1. Here’s the output of the code:

    tasty grape juice, or apple and yum?
    orange, thanks!
    tasty orange juice, or prune and juice?
    yum, thanks!
    tasty apple juice, or yum and orange?
    prune, thanks!
    tasty prune juice, or apple and prune?
    

    Table for the main() method
    The first row shows the initial value of all the variables (the values after the first six lines of the method are executed). A new row is created whenever a variable is updated.

    orange apple grape prune juice yum
    "apple" "yum" "juice" "orange" "grape" "prune"
    "orange"
    "prune"

    Table for the first call to fresh()
    In this first call, fresh(apple, juice, orange) is equivalent to fresh("yum", "grape", "apple") after the actual arguments in main() are evaluated.

    juice orange tasty
    "yum" "grape" "apple"

    The output of this call is as follows:

    tasty grape juice, or apple and yum?
    

    Table for the first call to tasty()
    In this first call, tasty("grape", prune) is equivalent to tasty("grape", "orange") after the actual arguments in main() are evaluated.

    orange apple
    "grape" "orange"

    This method does not do any printing, but it does return the string "orange" since the expression apple.length() evaluates to 6, which is greater than orange.length(), which is 5. Note: in main(), this "orange" return value is assigned to the juice variable.

    Table for the second call to fresh()
    In the second call, fresh(grape, prune, yum) is equivalent to fresh("juice", "orange", "prune") after the actual arguments in main() are evaluated.

    juice orange tasty
    "juice" "orange" "prune"

    The output of this call is as follows:

    tasty orange juice, or prune and juice?
    

    Table for the second call to tasty()
    In the second call, tasty(apple, orange) is equivalent to tasty("yum", "apple") after the actual arguments in main() are evaluated.

    orange apple
    "yum" "apple"

    This method returns the string "apple" since the expression apple.length() evaluates to 5, which is greater than orange.length(), which is 3. Note: this method’s return value is not used by main()!

    Table for the third call to fresh()
    In the third call, fresh(juice, "apple", apple) is equivalent to fresh("orange", "apple", "yum") after the actual arguments in main() are evaluated. Note: if you forgot to update the juice variable in main() after the first call to tasty(), you would have made a mistake here and done fresh("grape", "apple", "yum") instead!

    juice orange tasty
    "orange" "apple" "yum"

    The output of this call is as follows:

    tasty apple juice, or yum and orange?
    

    Table for the third call to tasty()
    In the third call, tasty(apple, yum) is equivalent to tasty("yum", "prune") after the actual arguments in main() are evaluated.

    orange apple
    "yum" "prune"

    This method returns the string "prune" since the expression apple.length() evaluates to 5, which is greater than orange.length(), which is 3. Note: in main(), this "prune" return value is assigned to the grape variable.

    Table for the fourth call to fresh()
    In the fourth call, fresh(yum, grape, orange) is equivalent to fresh("prune", "prune", "apple") after the actual arguments in main() are evaluated. Note: if you forgot to update the grape variable in main() after the third call to tasty(), you would have made a mistake here and done fresh("prune", "juice", "apple") instead!

    juice orange tasty
    "prune" "prune" "apple"

    The output of this call is as follows:

    tasty prune juice, or apple and prune?
    

    ↩

  2. str1.substring(0, 7) ↩

  3. str1.length() + str2.length() ↩

  4. str2.toUpperCase() ↩

  5. Either str2.toUpperCase().substring(0, 4) or str2.substring(0, 4).toUpperCase() will work. ↩

  6. str1.charAt(1) or str1.charAt(4) will work. ↩

  7. str2.charAt(1) or str2.charAt(6) will work. ↩

  8. str1.charAt(3) ↩

  9. The entire method is included below.

    public static int countA(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == 'a') {
                count = count + 1;
            }
        }
    
        return count;
    }
    

    ↩

  10. The entire method is included below.

    public static int count(String str, char ch) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == ch) {
                count = count + 1;
            }
        }
    
        return count;
    }
    

    ↩

  11. The entire method is included below. Another acceptable approach is to start the integer i at 0 and do a subtraction in the call to charAt().

    public static void printReverse(String str) {
        for (int i = str.length() - 1; i >= 0; i--) {
            System.out.print(str.charAt(i));
        }
    
        System.out.println();
    }
    

    ↩

  12. Below are two versions: the version that would print each character with a space, and the version that builds a new string with the characters of the string and the spaces.

    // the version that prints
    public static void printSpaced(String str) {
        for (int i = 0; i < str.length(); i++) {
            System.out.print(str.charAt(i));
            System.out.print(" ");
        }
    
        System.out.println();
    }
    
    // the version that concatenates and returns a string
    public static String getSpaced(String str) {
        String out = "";
    
        for (int i = 0; i < str.length(); i++) {
            out = out + str.charAt(i) + " ";
        }
    
        return out;
    }
    

    ↩

  13. A calculation is required to determine the number of spaces to print. You can store the calculation in a variable, or you can do it in a for loop.

    public static void padString(String str, int maxLength) {
        int numSpaces;
    
        if (str.length() >= maxLength) {
            numSpaces = 0;
        } else {
            numSpaces = maxLength - str.length();
        }
    
        for (int i = 0; i < numSpaces; i++) {
            System.out.print(" ");
        }
    
        System.out.println(str);
    }
    
    // ...or, you could do it with just a for loop
    public static void padStringShorter(String str, int maxLength) {
        for (int i = maxLength - str.length(); i > 0; i--) {
            System.out.print(" ");
        }
    
        System.out.println(str);
    }
    

    ↩

  14. The method is included below.

    public static void printChant(String str, int count) {
        for (int i = 0; i < count; i++) {
            System.out.print(str + "! ");
        }
    
        System.out.println();
    }
    

    ↩

  15. The method is included below.

    public static String getChant(String str, int count) {
        String partial = "";
    
        for (int i = 0; i < count; i++) {
            partial = partial + str + "! ";
        }
    
        return partial;
    }
    

    ↩

  16. The method is included below.

    public static String dechant(String str) {
        int markPosition = str.indexOf('!');
        return str.substring(0, markPosition);
    }
    

    ↩

  17. The method is included below.

    public static String shift(String str, int offset) {
        String shifted = "";
    
        /*
         * Note that the parentheses around i - offset + str.length()
         * are required, otherwise the % expression would be evaluated
         * first.
         */
        for (int i = 0; i < str.length(); i++) {
            shifted += str.charAt((i - offset + str.length()) % str.length());
        }
    
        return shifted;
    }
    

    Convince yourself why we need to use i - offset + str.length() by creating a table of values, if necessary. ↩

Last updated on July 1, 2025.