CS 112
Spring 2024

Lab 2: Strings and arrays; a first look at reference types

Creating the necessary folder

  1. If you haven’t already created a folder named cs112 for your work in this course, follow these instructions to do so.

  2. Then create a subfolder called lab2 within your cs112 folder, and put all of the files for this lab in that folder.

Task 1: Working with Java Strings

Task 1.1: String objects and their methods

In Problem Set 2, there are several problems in which you will need to work with String objects in Java.

It turns out that Java lacks many of Python’s built-in operators and functions for strings. Instead, most operations involving strings – including indexing and slicing – are done using methods that are inside the string object.

If you would like to review, this is an example of a code trace using Java Strings.

The table below compares the ways in which some common string operations would be accomplished in Python and Java:

operation

in Python

in Java

assigning to a variable (and, in Java, declaring the variable)

s1 = 'Boston'
s2 = "University"

String s1 = "Boston";
String s2 = "University";

concatenation

s1 + s2

s1 + s2

finding the number of characters

len(s1)

s1.length()

indexing
(note: Java does not have negative indices)

s1[0]
s2[-1]

s1.charAt(0)
s2.charAt(s2.length()-1)
(see the notes below the table for a key fact about this method)

slicing

s1[1:4]
s2[3: ]
s1[ :5]

s1.substring(1, 4)
s2.substring(3)
s1.substring(0, 5)

converting all letters to uppercase

s1.upper()

s1.toUpperCase()

converting all letters to lowercase

s2.lower()

s2.toLowerCase()

determining if a substring is in a string

s2 in s1
'sit' in s2

s1.contains(s2)
s2.contains("sit")

finding the index of the first occurence of a character or substring

s1.find("o")
s2.find('ver')

s1.indexOf('o')
s2.indexOf("ver")

testing if two strings are equivalent

s1 == s2
s1 == 'Boston'

s1.equals(s2)
s1.equals("Boston")

Additional notes:

Task 1.2: Using String methods

To ensure that you understand how the above string operations work in Java, let’s write a simple Java test program that you can use to play around with the different string operations.

Getting started

  1. If you haven’t already done so, create a folder named lab2 for your work on this lab. You can find instructions for creating folders here.

  2. As needed, open your lab2 folder using the File->Open Folder or File->Open menu option in VS Code.

  3. Select File->New File, which will open up an empty editor window.

  4. Select File->Save, and give the new file the name StringTest.java.

Here are the tasks you should perform as part of your StringTest class:

  1. Create a class header and a main method.

  2. In the main method, begin by initializing two string variables that we will use in the later steps:

    String s1 = "Boston";
    String s2 = "University";
    

    If you have done everything correctly, the statements:

    System.out.println(s1);
    System.out.println(s2);
    

    should output:

    Boston
    University
    

    If for some reason you don’t see this output, make whatever changes are needed before proceeding.

  3. We’re now going to solve a series of puzzles in which we construct an expression involving operations on s1 and/or s2 to produce a specified target value.

    For example, let’s say that we want to construct an expression involving s1 or s2 that produces the following value:

    "ton"
    

    One possible expression that works for this puzzle is s1.substring(3, 6). To see this, we can add the line:

    System.out.println( s1.substring(3, 6) );
    

    which should output:

    ton
    
  4. Now solve the puzzles below. As you do so, add a println statement to your main method to test each expression that you construct.

    1. Construct an expression involving s1 or s2 that produces the following value:

      "Uni"
      
    2. Construct an expression involving s1 or s2 that produces the following value:

      "UNI"
      

      Hint: Chain two method calls together. For example:

      System.out.println( s1.toLowerCase().substring(0, 3) );
      

      should output:

      bos
      
    3. Construct an expression involving s1 or s2 that produces the following value:

      'v'
      

      Note that the single quotes mean that you must produce a char, not a String. See the notes under the table above that discuss the char type.

    4. Construct an expression involving s1 or s2 that produces the following value:

      "STONE"
      
  5. Write a static method called replaceStart that takes two strings s1 and s2, and does the following:

    • If the length of s1 (call it s1Len) is less than the length of s2, the method returns a string in which the first s1Len characters of s2 are replaced by s1. For example:

      System.out.println( replaceStart("abc", "xxxxxxx") );
      

      should output:

      abcxxxx
      

      and,

      System.out.println( replaceStart("hello", "xxxxxxx") );
      

      should output:

      helloxx
      
    • If the length of s1 is greater than or equal to the length of s2, the method just returns s1. For example:

      System.out.println( replaceStart("hello", "bye") );
      

      should output:

      hello
      
  6. Why does the method replaceStart need to be called from within the println method? In other words, what would you expect to happen if our program just made the call to replaceStart on its own line, rather than calling it as part of a println? Make sure you understand.

Task 2: Arrays and references

To get the most out of this task, draw out a memory diagram of the arrays on a piece of paper (follow examples we did in lecture, and the instructions of your TA). This is the best way to understand the correct answer to each of the questions, and why.

  1. Let’s draw what things look like in memory for the each of the following code snippets:

    // snippet A
    int[] a1 = {1, 2, 3, 4};
    int[] a2 = a1;
    
    // snippet B
    int[] b1 = {1, 2, 3, 4};
    int[] b2 = {1, 2, 3, 4};
    
  2. Given the two snippets above, what is the value of the following expression?

    a1 == a2
    
  3. Given the two snippets above, what is the value of the following expression?

    b1 == b2
    
  4. Consider the following static method:

    public static void mystery(int[] vals) {
        for (int i = 0; i < vals.length; i++) {
            vals[i] *= -1;
        }
    
        int[] vals2 = new int[vals.length];
        for (int i = 0; i < vals.length; i++) {
            vals2[i] = vals[i];
        }
        vals = vals2;
    
        for (int i = 0; i < vals.length; i++) {
            vals[i] += 2;
        }
    }
    

    What does the array a1 look like after the execution of the following code snippet, which you many assume is part of the main method of a valid Java class?

    int[] a1 = {1, 2, 3, 4};
    mystery(a1);
    

    Draw pictures to show what things look like in memory. You may find it helpful to use the following template, which shows separate method frames for main() and mystery():

    +--------------+
    | mystery      |
    | -------      |
    |       +----+ |
    | vals2 |    | |
    |       +----+ |
    |       +----+ |
    |  vals |    | |
    |       +----+ |
    +--------------+
    | main         |
    | ----         |
    |       +----+ |
    |    a1 |    | |
    |       +----+ |
    +--------------+
    

Task 3: Array methods

Getting started

  1. As needed, open your lab2 folder using the File->Open Folder or File->Open menu option in VS Code.

  2. Select File->New File, which will open up an empty editor window.

  3. Select File->Save, and give the new file the name ArrayPractice.java.

Here are the tasks you should perform as part of your ArrayPractice class:

  1. Before the class header, you should include the following statement, which will give us access to the methods in the Arrays class:

    import java.util.*;
    
  2. Create a class header and a main method, and add the following initial statements to your main method:

    int[] a = {2, 4, 6, 8};
    
    System.out.println( a );
    
    // What do you expect to see?
    
    System.out.println( Arrays.toString(a) );
    
    // Now, what do you expect to see?
    
  3. Write a static method named equals that takes two arrays of integers and determines if the two arrays are identical (i.e. same elements in the same positions). The method should return true or false accordingly.

    For this (and each of the following methods), you will need to add calls to your main method to test them.

    Example:

    int[] a1 = {1, 2, 3, 4};
    int[] a2 = {1, 2, 3, 4};
    System.out.println( a1 == a2 );
    System.out.println( equals(a1, a2) );
    

    You should expect to see:

    false
    true
    

    Congratulations! You just wrote your own equals method for arrays! However the Arrays class contains many methods, one of which is the equals method. To use the built-in Arrays method, try this:

    Example:

    System.out.println( Arrays.equals(a1, a2) );
    

    You should expect to see:

    true
    
  4. Write a static method named square that takes an array of integers and squares each element of the array.

    This method does not need to return anything. (If you’re not sure why, please ask!)

    Example:

    int[] a1 = {1, 2, 3, 4};
    square(a1);
    System.out.println( Arrays.toString(a1) );
    

    You should expect to see:

    [1, 4, 9, 16]
    

Extra Practice!

If you get through the exercises above, congratulations!

For extra practice, you can try some exercises from an excellent site called Practice-It.