Void/Non-Void Methods, Concatenation, Literals, String Objects and Methods
A lesson of Collegeboard topics 2.3 - 2.7, making sure to focus on the FRQs
wget link
Strings, String Literals, String Objects
Java String Basics Review
- String Object Creation:
- Literals: Assigning a string value within double quotes directly.
- Using
new
Keyword: Creating a new instance of a string object using thenew
keyword. - String Pool: Strings created using literals are stored in the string pool, optimizing memory usage.
- String Concatenation:
- Concatenation Operator (
+
): Combining strings and other data types using the+
operator.
- Concatenation Operator (
- StringBuilder:
- StringBuilder Class: Efficient for manipulating strings, especially for frequent concatenation or modification operations.
- Mutable: StringBuilder objects are mutable, allowing for in-place modification without creating new objects.
- String Methods:
indexOf
Method: Finds the first occurrence of a substring within a string and returns its index.- Returning String Types: Methods like
substring
,replace
, andtoUpperCase
return new String objects. - Returning int and boolean Types: Methods like
length
,equals
, andcompareTo
returnint
orboolean
values.
public class Example {
public static void main(String[] args) {
// String Object Creation
String str1 = "Tanay";
String str2 = new String("Patel");
// String Concatenation
String concat = str1 + ", " + str2;
// StringBuilder
StringBuilder builder = new StringBuilder();
builder.append(str1);
builder.append(" ");
builder.append(str2);
String result = builder.toString();
// String Methods
int index = concat.indexOf("W");
boolean isEqual = str1.equals(str2);
int length = result.length();
int comparison = str1.compareTo(str2);
}
}
public class StringCharConversion {
public static void main(String[] args) {
// String to char
String str = "Hello";
char[] charArray = str.toCharArray(); // Convert String to char array
for (char c : charArray) {
System.out.println(c); // Print each char
}
// Char to String
char[] chars = {'W', 'o', 'r', 'l', 'd'};
String newStr = new String(chars); // Convert char array to String
System.out.println(newStr); // Print the new String
}
}
StringCharConversion.main(null);
H
e
l
l
o
World
College Board 2021 FRQ 1
public class WordMatch {
private String secret;
public WordMatch(String word) {
this.secret = word;
}
public int scoreGuess(String guess) {
int count = 0;
for (int i = 0; i <= secret.length() - guess.length(); i++) {
if (secret.substring(i, i + guess.length()).equals(guess)) {
count++;
}
}
return count * guess.length() * guess.length();
}
public String findBetterGuess(String guess1, String guess2) {
if (scoreGuess(guess1) > scoreGuess(guess2)) {
return guess1;
}
if (scoreGuess(guess2) > scoreGuess(guess1)) {
return guess2;
}
if (guess1.compareTo(guess2) > 0) {
return guess1;
}
return guess2;
}
public static void main(String[] args) {
WordMatch game = new WordMatch("example");
String guess1 = "ex";
String guess2 = "ample";
System.out.println("Better Guess: " + game.findBetterGuess(guess1, guess2));
}
}
WordMatch.main(null);
Better Guess: iii
Void and Non-Void Methods
Review: Void & Non-Void Methods
- A void method is a method that does not return any data.
- A non-void method is a method that is defined as a data type and returns that data type.
FRQ Example of Non-Void Methods: 2017 FRQ #1
This question involves identifying and processing the digits of a non-negative integer. The declaration of the Digits
class is shown below. You will write the constructor and one method for the Digits
class.
public class Digits {
private ArrayList<Integer> digitList;
public Digits(int num) {}
public boolean isStrictlyIncreasing() {
}
}
Since we are looking at methods for this lesson, we will skip ahead to part b, which is to write the isStrictlyIncreasing()
method.
Since this part of the FRQ is of type Methods & Control Structures, we must think of how we can use methods, loops, conditionals, and other structures to write this method.
The method isStrictlyIncreasing()
needs to return true if the digits from left to right are increasing.
From this, two potential control structures come into play:
- A
for
loop to iterate through the digits from left to right - A conditional in the loop to compare different digits to each other and check if the list is increasing.
Let’s first start with the for
loop:
public boolean isStrictlyIncreasing() {
// Iterate through the list
for (int i = 0; i < digitList.size() - 1; i++) {
}
}
The code above correctly iterates through each digit of the number.
Now, let’s apply our conditional. We want to check if the digits are increasing from left to right. A way to do this is to compare the index we are on in the loop with the index after it.
If the index after the one we are on is greater, we continue, and if its less than the one we are on, we stop.
Here’s how I put that in Java:
public boolean isStrictlyIncreasing() {
for (int i = 0; i < digitList.size() - 1; i++) {
// Check if the element after the index currently pointed to is greater or less than. If the one we are pointing to is greater, we return false, because it is therefore not strictly increasing.
if (digitList.get(i).intValue() > digitList.get(i + 1).intValue()) {
return false;
}
}
return true;
}
Teacher Hacks Example of Void Methods: Do Nothing By Value
Consider the following code, what do you think it does:
class Triple<T1, T2, T3> {
T1 one;
T2 two;
T3 three;
Triple(T1 one, T2 two, T3 three) {
this.one = one;
this.two = two;
this.three = three;
}
public T1 getOne() { return this.one; }
public void setOne(T1 one) { this.one = one; }
public T2 getTwo() { return this.two; }
public void setTwo(T2 two) { this.two = two; }
public T3 getThree() { return this.three; }
public void setThree(T3 three) { this.three = three; }
}
public class DoNothingByValue {
public int[] arr;
public int val;
public String word;
// changed to show what is happening
public DoNothingByValue (int [] arr, int val, String word) {
this.arr = new int[5];
this.val = 0;
this.word = word.substring(0, 5);
System.out.print("constructor: ");
for (int k = 0; k < arr.length; k++) {
arr[k] = 0; // int array is initialized to 0's, not needed
System.out.print(arr[k] + " ");
}
System.out.println(this.word);
}
// Local instance variables
// IntelliJ shows that something is wrong, calling the values passed as parameters as local
public static void changeIt(int [] arr, int val, String word) {
arr = new int[5];
val = 0;
word = word.substring(0, 5);
System.out.print("changeIt: "); // added
for (int k = 0; k < arr.length; k++) {
arr[k] = 0;
System.out.print(arr[k] + " "); // added
}
System.out.println(word); // added
}
// Variable name are Reference
// names of variables make no difference, they are just references to addresses
public static void changeIt2(int [] nums, int value, String name) {
nums = new int[5]; // new creates new memory address
value = 0; // primitives are pass by value
name = name.substring(0, 5); // all wrapper classes have automatic "new", same as word = new String(word.substring(0, 5));
// this loop changes nums locally
System.out.print("changeIt2: ");
for (int k = 0; k < nums.length; k++) {
nums[k] = 0;
System.out.print(nums[k] + " ");
}
System.out.println(name);
}
// If you want to change values, think about Return values, but you are limited to one in Java
// changed to show what is happening
public static String changeIt3(int [] arr, String word) {
word = new String(word.substring(0, 5)); // wrapper class does a "new" on any assignment
System.out.print("changeIt3: ");
for (int k = 0; k < arr.length; k++) {
arr[k] = 0; // int array is initialized to 0's, not needed
System.out.print(arr[k] + " ");
}
System.out.println(word);
return word;
}
// Variable inside of Object Triple are references
public static Triple<int[], Integer, String> changeIt4(Triple<int[], Integer, String> T) {
T.setOne(new int[5]);
T.setTwo(0); // primitives are pass by value
T.setThree(T.getThree().substring(0, 5)); // all wrapper classes have automatic "new", same as word = new String(word.substring(0, 5));
// this loop changes nums locally
System.out.print("changeIt4: ");
for (int i : T.getOne()) {
System.out.print(i + " ");
}
System.out.println(T.getThree());
return T;
}
// Original method changed to main in order to be a Tester
public static void main(String[] args) {
// Does nothing
int [] nums = {1, 2, 3, 4, 5};
int value = 6;
String name = "blackboard";
System.out.println("Do Nothings");
// dumb and useless
changeIt(nums, value, name);
// dumber and useless
changeIt2(nums, value, name);
System.out.print("main: ");
for (int k = 0; k < nums.length; k++) {
System.out.print (nums[k] + " ");
}
System.out.print(value + " ");
System.out.print(name);
System.out.println();
System.out.println();
// int[] by reference, return value -- not complete
System.out.println("Limited return");
int[] nums2 = {1, 2, 3, 4, 5};
value = 6;
name = "limited";
name = changeIt3(nums2, name);
System.out.print("main2: ");
for (int num : nums2) {
System.out.print(num + " ");
}
System.out.print(value + " ");
System.out.print(name);
System.out.println();
System.out.println();
// Class/Object
System.out.println("Do Something with Class");
int[] nums3 = {1, 2, 3, 4, 5};
value = 6;
name = "classy";
DoNothingByValue doSomething = new DoNothingByValue(nums3, value, name);
System.out.print("main3: ");
for (int num : doSomething.arr) { // should be teaching enhanced for loop on arrays
System.out.print(num + " ");
}
System.out.print(doSomething.val + " ");
System.out.print(doSomething.word);
System.out.println();
System.out.println();
// Generics
System.out.println("Do Something with Generics");
int[] nums4 = {1, 2, 3, 4, 5};
value = 6;
name = "generics";
Triple<int[],Integer,String> tri = changeIt4(new Triple<>(nums4, value, name));
System.out.print("main: ");
for (int num : tri.getOne())
System.out.print (num + " ");
System.out.print(tri.getTwo() + " ");
System.out.print(tri.getThree());
}
}
// This class can be used to pass variables by reference
DoNothingByValue.main(null);
Do Nothings
changeIt: 0 0 0 0 0 black
changeIt2: 0 0 0 0 0 black
main: 1 2 3 4 5 6 blackboard
Limited return
changeIt3: 0 0 0 0 0 limit
main2: 0 0 0 0 0 6 limit
Do Something with Class
constructor: 0 0 0 0 0 class
main3: 0 0 0 0 0 0 class
Do Something with Generics
changeIt4: 0 0 0 0 0 gener
main: 0 0 0 0 0 0 gener
This code first takes
public static void changeIt(int [] arr, int val, String word) {
arr = new int[5];
val = 0;
word = word.substring(0, 5);
System.out.print("changeIt: "); // added
for (int k = 0; k < arr.length; k++) {
arr[k] = 0;
System.out.print(arr[k] + " "); // added
}
System.out.println(word); // added
}
This method:
- Is a void method
- Does not return any data but instead prints it in the console
- Has a control structure
- The
for
loop
- The
- Manipulates a list through its
for
loop control structure
Recap
For Methods & Control Structures questions, here are the steps we recommend:
- Write a quick list of M&CT you know to remind yourself:
- Void methods
- Non-void methods
- Most of the time, all methods are already defined, you just have to write them
- For loops
- While loops
- Conditional statements
- Nested loops
- Nested conditionals
- Switch/case
- I wouldn’t count on using this
- Map out your code using basic diagrams as pseudo code
- As you go, check off M&CT off of your list whenever you use them
- Remember that they can be used more than once
- Try going into a bit more detail when you start applying the M&CT to your pseudo code
- As you go, check off M&CT off of your list whenever you use them
- Write your code out (yes, it is in pen)
- Remember to have a mental debugger
- If you need practice, do the debugging event lesson again and play around with different breakpoints, errors, etc.
- Remember to have a mental debugger