Lecture 6:
ArrayLists & Inheritance
CS 136: Spring 2024
Katie Keith
Record on Zoom
Weekly routine
Wed.
Thurs.
Fri.
Sun.
Mon.
Tues.
Sat.
Lab due 10pm for Weds labs
Plus
Quiz 1 (Feb 28)
Midterm Exam (March 20)
Final Project
Final Exam
Honor
Code
Two Late Days on Labs
*Max 1 per lab
Start Early!
Lab released
Attend lab
Attend lab
Lab due 10pm for Thurs labs
📣 Announcements
🎯 Today’s Learning Objectives
📚Readings
Task: Object-oriented Zoo!
Animal.java
💻
Reference type with toString()
public class Animal{
public String name;
public final String species;
public Animal(String name, String species){
this.name = name;
this.species = species;
}
public String toString(){
return this.name +" the "+ this.species + "!";
}
}
When we create a new class (new reference type), we typically write a custom toString() method which provides a readable string representation of the object (and can help us debug when the object is printed).
This is helpful because we will know the values of the object’s instance variables.
Review: Making arrays
Making arrays in Java requires three steps:
double[] a;
a = new double[10];
for (int i = 0; i < 10; i++){
a[i] = 0.0;
}
We’re using new because an Array is a reference type
All elements in an array are the same type (here, a double)
We specify up-front the fixed number of elements in the array
The square brackets allow us to access the ith element of a.
Remember: We start at index 0.
1.
2.
3.
1.
2.
3.
Example: Arrays of objects
Animal[] animalTracker = new Animal[3];
animalTracker[0] = new Animal("Leo", "Lion");
animalTracker[1] = new Animal("Manny", "Elephant");
animalTracker[2] = new Animal("Stripes", "Zebra");
Declares and initializes an array with three elements, where each element is will be an object from the Animal class.
As we initialize each element in the array, we also have to use the new keyword since each of these elements is a new object.
Java’s Packages
In Java, a package is a grouping of related classes.
To create a package we:
In our example, this looks like
package zoostuff;
package zoostuff;
Zoo.java
Animal.java
ZooKeeper.java
💻
Compiling entire packages
mkdir bin
javac -d bin zoostuff/*.java
java -cp bin zoostuff.Zookeeper
Terminal
Makes a new folder called “bin”
Here, * is a “wildcard” so this gets all files that end with .java
When used with javac, -d stands for “destination directory” for the .class files
When used with java, -cp stands for “classpath” and tells JVM where to look for the .class files
Now we call the package name (zoostuff) followed by the class we want to execute main in (here, Zookeeper)
✅
✅
🎯 Today’s Learning Objectives
Review: Array capacity is immutable
Animal[] animalTracker = new Animal[2];
animalTracker[0] = new Animal("Leo", "Lion");
animalTracker[1] = new Animal("Manny", "Elephant");
animalTracker[2] = new Animal("Stripes", "Zebra");
Q: When might that be a problem?
ArrayList
An ArrayList (also called a “dynamic array”) acts like an Array but an ArrayList’s capacity can grow as needed.
import java.util.ArrayList;
To use ArrayLists in Java, we’ll need this import statement at the top of a .java file.
This week’s road-map
Declaring and Creating an ArrayList
ArrayList<String> animalNames = new ArrayList<String>();
Variable name
Type of each element of the ArrayList
These angle brackets indicate this is a generic type
(We’ll dig into generics a little later on this week.)
Default capacity. Unlike Arrays we don’t have to specify an initial capacity and our ArrayList will grow dynamically.
ArrayLists: size vs. capacity
An ArrayList’s size refers to the number of non-null elements it contains.
An ArrayList’s capacity refers to the size of the array that backs the ArrayList.
“Leo”
“Manny”
“Stripes”
null
int size = animalNames.size(); // 3
// In our example, the capacity is 4 (last element is null)
Our “model” of the underlying array that backs the ArrayList
ArrayLists need Wrapper Types
ArrayList<Integer> numbers = new ArrayList<Integer>(10);
Need to use the wrapper type
Optional: we can declare an initial capacity of the ArrayList here.
Wrapper types
When we need to represent the value from a primitive type as a reference type, Java supplies built-in reference types known as wrapper types for each of the eight primitive types.
Autoboxing and unboxing
Java automatically converts between values from a wrapper type and the corresponding primitive type.
ArrayLists need Wrapper Types
ArrayList<Integer> numbers = new ArrayList<Integer>(10);
Need to use the wrapper type
Optional: we can declare an initial capacity of the ArrayList here.
Adding elements to an ArrayList
animalNames.add(“Leo”);
animalNames.add(“Manny”);
animalNames.add(“Stripes”);
ArrayList<String> animalNames = new ArrayList<String>();
Instance method
“Leo”
“Manny”
“Stripes”
null
Retrieving elements from an ArrayList
animalNames.get(0); // “Leo”
animalNames.get(2); // “Stripes”
Instance method
“Leo”
“Manny”
“Stripes”
null
ArrayLists expand automatically
animalNames.add(“Moo Deng”);
“Leo”
“Manny”
“Stripes”
“Mark”
“Toni”
Preview Weds:
In our implementation, we’ll have to choose a growth factor, create a new array, copy elements, and update the references…
When an ArrayList is at capacity, and a new element is added, the underlying ArrayList expands capacity automatically.
“Moo Deng”
null
null
null
null
“Leo”
“Manny”
“Stripes”
“Mark”
“Toni”
Removing elements from an ArrayList
animalNames.remove(“Manny”);
“Leo”
“Manny”
“Stripes”
“Mark”
null
“Leo”
null
“Stripes”
“Mark”
null
One more null element
Element shift: each element after the removed element is shifted one index to the left
If there are duplicates, only the first occurrence of the element is removed
Replacing elements in an ArrayList
animalNames.set(1, "Moo Deng");
“Leo”
“Moo Deng”
“Stipes”
“Mark”
null
Index
“Leo”
“Manny”
“Stripes”
“Mark”
null
Enhanced for-loop
for (String name : animalName){
System.out.println(name+ " is here!");
}
ArrayList
Type of the local variable (must match declared type of elements in the ArrayList).
In Java, to iterate over Arrays, ArrayLists (or other collections), we can use an “enhanced for-loop”
Local variable that holds the current element of the collection or array on each iteration of the loop.
public static ArrayList<String> compareRemove(ArrayList<String> animalNames){
for (String name : animalNames){
if ( name.charAt(0) > 'M'){
animalNames.remove(name);
}
}
return animalNames;
}
Suppose write compareRemove() below to remove animals’ names from the ArrayList if they begin after the letter ‘M’. However, we get the following runtime error. What is wrong and how could we fix it?
animalNames
“Leo”
“Moo Deng”
“Stipes”
“Mark”
“Stipes”
💡Think-pair-share
AnimalsArrayList.java
💻
✅
✅
✅
✅
🎯 Today’s Learning Objectives
Inheritance: subclassing
Java supports an inheritance mechanism known as subclassing. Subclassing enables a programmer to add functionality to a class without rewriting an entire class from scratch.
extends
Superclass
Subclass
The extends keyword in Java enforces that the subclass inherits all instance methods and instance variables from the superclass.
class FastCat extends Animal{
...
}
Implementing inherited classes
class FastCat extends Animal{
public double maxSpeed; //MPH
public FastCat(String name, String species, double maxSpeed){
super(name, species);
this.maxSpeed = maxSpeed;
}
@Override
public String toString(){
return this.name + " the "+ this.species + " is super fast,"
+ this.maxSpeed +"max MPH!";
}
}
In Java, the keyword extends indicates that the class is inheriting from a superclass
Here, super calls the superclass’s constructor from the subclass’s constructor
subclass
superclass
The @ symbol is an “annotation” and @Override indicates that the annotated method overrides a method in the superclass with the same name. This will be checked by the compiler.
FastCats.java
💻
A subclass is the type of its superclass
A subclass not only inherits the instance variables and methods of the superclass, but it also inherits the types of the superclass.
ArrayList<Animal> theAnimals = new ArrayList<Animal>();
theAnimals.add(new Animal("Leo", "Lio"));
theAnimals.add(new FastCat("Claire", "Cheetah", 70.0));
Legal because FastCat is a Animal type due to inheritance
Style: JavaDoc comments and @param
/**
* An instance method to increase the maxSpeed of a FastCat
* @param amountIncrease is the amount to increase the FastCats's speed
*/
public void increaseSpeed(int amountIncrease){
this.maxSpeed += amountIncrease;
}
In JavaDocs, annotations start with @
Here, @param describes the input parameters of a method
This indicates this is a JavaDoc comment: a special type of block comment that describes a method’s specification.
✅
✅
✅
✅
✅
🎯 Today’s Learning Objectives