Class 10 — Monday, September 28

What a name holds, == against .equals, and text that answers questions about itself.

Wednesday you used the dot on a text without a name for it. Today it gets its name, and one question it raises: when are two texts the same?

[CU] 3.1 — Strings and [DCIC] 12.2 — Understanding Equality were due before today.

Quiz 3 runs twice on Brightspace, once now and once at the end of class. The higher attempt counts.

Outline

  1. What a name holds — a number, or where a text is
  2. Same address, or same text? — predict first, then run
  3. Text that answers questions about itself — pairs, at the keyboard
  4. Keep going — nine more, harder as it goes
  5. Predict, then run — three short ones from the reading
  6. Before Wednesday

1. What a name holds

Screens off. The drawings are on the projector.

int w = stripeWidth(10);
String r = stripeRow(1);

w holds 60. The number sits in the name.

r does not hold ######. The text sits somewhere in memory, and r holds where: an address. The reading draws it as a directory of names on the left and a heap of things on the right:

directory          heap
w  →  60
r  →  1001         1001: "######"

Coles calls int a primitive type and String a reference type for the same reason.

So what does toUpperCase() do to the name it is called on? Nothing. It makes a new text and gives it back; the name still says where the old one is. Coles 3.1.5, on your own machine:

String animal = "quokka";
animal.toUpperCase();
IO.println(animal);

Prints quokka.

directory          heap
animal  →  1002    1002: "quokka"
                   1003: "QUOKKA"    made by toUpperCase(); no name holds it

To make animal say where the new text is, assign:

animal = animal.toUpperCase();
IO.println(animal);

Prints QUOKKA. In Pyret that line needed var and :=. Java’s = does both jobs.

directory          heap
animal  →  1004    1002: "quokka"
                   1003: "QUOKKA"
                   1004: "QUOKKA"    made by the second toUpperCase()

1003 and 1004 print the same. One address, or two?

2. Same address, or same text?

Predict first. Nobody runs it until I say.

Wednesday Check.is("#".repeat(6), "######") would have passed. Now, in main:

IO.println("#".repeat(6) == "######");
IO.println("#".repeat(6).equals("######"));
heap
1005: "######"    made by "#".repeat(6), while the program runs
1006: "######"    the literal "######", one copy for the whole program

== asks: same address? 1005 and 1006: false. .equals asks: same text? ###### and ######: true. The reading calls the first reference equality and the second structural equality, and says every language has both.

A number has no address: it sits in the name itself, so stripeWidth(10) == 60 is fine, and always was. That is why Check.is uses == for numbers and .equals for text: open Check.java and find the line.

Two texts typed the same in the program share one address. Java keeps a single copy of "######" wherever it is written, so "######" == "######" is true. Text made while the program runs, by repeat or by +, gets a new address.

3. Text that answers questions about itself

Pairs. One keyboard; drivers swap at the break.

Open Wednesday’s Stripe.java in IDEA, under IdeaProjects. No file? Clone the starter again in IDEA, with Wednesday’s steps: https://github.com/cu-cs-labs/cmsc-120-stripe. Or open the same two files on OneCompiler: https://onecompiler.com/java/4544z33u6.

Each function gets a // line above it and two Check.is lines in main, worked out before the body. Every method below is one the text already has; the reading lists them.

shout

String shout(String s)

shout("java") is JAVA!. toUpperCase, then +.

initial

The first letter, as text.

String initial(String name)

initial("Ada") is A. substring(0, 1): from position 0, up to but not including position 1. Positions start at 0.

lastOf

The last letter.

String lastOf(String s)

lastOf("Java") is a. substring with one number runs to the end, and length() knows where the end is.

sameText

boolean sameText(String a, String b)

sameText("java", "java") is true; sameText("Java", "java") is false. One of your checks is Check.is(sameText("#".repeat(6), "######"), true).

stripes

How many stripes wide a row is, when a stripe is six characters.

int stripes(String row)

stripes("############") is 2.

swapHalves

The reading’s listing 3.1.2, as a function: the second half, then the first.

String swapHalves(String s)

swapHalves("capybara") is baracapy. A name made inside a function holds its value for the rest of that function: after int n = s.length();, n is the length in every line below it.

Done when Check.done() prints Looks shipshape with two checks per function. The first four come first; stripes and swapHalves are for the pairs that get there.

A red StringIndexOutOfBoundsException is a position past the end of the text. Read the line number, then count the positions again from 0.

4. Keep going

In order; each one is harder than the one before. Two checks each, then the next. The last two are for the pairs that found the first seven easy.

position

Where a piece of text sits inside another, counting from 0, and -1 when it is not there.

int position(String s, String piece)

position("Java", "v") is 2; position("Java", "z") is -1. The text already knows; look for indexOf in the reading.

middle

The character at position length / 2, as text.

String middle(String s)

middle("cat") is a; middle("Java") is v; middle("a") is a.

beforeAt and domain

The two halves of an email address.

String beforeAt(String email)
String domain(String email)

beforeAt("ada@example.edu") is ada; domain("ada@example.edu") is example.edu. position finds the @; substring does the rest.

route

The reading’s listing 3.1.3: three parts joined by -.

String route(String from, String to, int flight)

route("JFK", "HEL", 235) is JFK-HEL-235. Write it twice: once with +, once with String.join. In which of the two is the thing on the left of the dot a class, and why does that one need String.valueOf?

censor

Every copy of a word replaced by that many *.

String censor(String s, String word)

censor("no darn way", "darn") is no **** way; censor("fine", "darn") is fine. replace swaps every copy at once, and repeat makes the stars.

pad

The text with spaces in front of it, so that it is exactly width long.

String pad(String s, int width)

pad("42", 5) is 42; one of your checks is Check.is(pad("42", 5).length(), 5). Then work out what pad("Java", 2) does, and run it. Coles 3.1.4 has the name of what you see.

between

The text between the first open and the first close after it.

String between(String s, String open, String close)

between("<b>bold</b>", "<b>", "</b>") is bold; between("say (hi) now", "(", ")") is hi; and between("x) (y)", "(", ")") is y. The last one is the check that catches the easy wrong body. indexOf can start looking from a position: s.indexOf(close, start).

isBefore

Whether a comes before b in alphabetical order.

boolean isBefore(String a, String b)

isBefore("apple", "banana") is true; isBefore("banana", "apple") and isBefore("apple", "apple") are false. compareTo gives back a number, negative when the first comes first. Then try isBefore("Zebra", "apple") and explain the answer to your partner.

count

How many times piece occurs in s. Without a loop: Java has one, you have not met it, and you do not need it.

int count(String s, String piece)

count("banana", "a") is 3; count("banana", "an") is 2; count("banana", "x") is 0. replace can delete, and length can measure what is gone.

5. Predict, then run

Write the answer down before running. Each takes a minute.

Two names, one address, then a new one:

String s = "quokka";
String t = s;
t = t.toUpperCase();
IO.println(s);
IO.println(t);
IO.println(s == t);

Coles 3.1.7. How long is each?

IO.println("A\nB".length());
IO.println("say \"hi\"".length());
IO.println("\\".length());

Coles 3.1.1:

IO.println("2" + 3 + 5);
IO.println(2 + 3 + "5");

6. Before Wednesday

A4 is due Tuesday, September 29. Part A is five minutes on Brightspace; Part B is Wednesday’s file, finished.

Wednesday opens with A4 presentations.