Class 10 — Monday, September 28
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
- What a name holds — a number, or where a text is
- Same address, or same text? — predict first, then run
- Text that answers questions about itself — pairs, at the keyboard
- Keep going — nine more, harder as it goes
- Predict, then run — three short ones from the reading
- 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.