0% found this document useful (0 votes)
6 views

[61B FA24] Lecture 10 - Inheritance 3_ Iterators, Object Methods

The document outlines a lecture on implementing an ArraySet in Java, focusing on iteration methods and object methods like toString and equals. It discusses the enhanced for loop, iterator methods, and the need for the ArraySet class to implement the Iterable interface to support these features. The lecture also covers basic functionalities of the ArraySet, including methods for adding elements and checking for their presence.

Uploaded by

sunxiaolong0728
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

[61B FA24] Lecture 10 - Inheritance 3_ Iterators, Object Methods

The document outlines a lecture on implementing an ArraySet in Java, focusing on iteration methods and object methods like toString and equals. It discusses the enhanced for loop, iterator methods, and the need for the ArraySet class to implement the Iterable interface to support these features. The lecture also covers basic functionalities of the ArraySet, including methods for adding elements and checking for their presence.

Uploaded by

sunxiaolong0728
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 51

Iterators,

Lecture 10 (Inheritance 3)

Object
Methods
CS61B, Fall 2024 @ UC Berkeley
Slides credit: Josh Hug

1
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable

Today’s Goal: Object Methods


• == vs. equals
ArraySet • toString
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
Sets in Java and Python

Today’s goal: Build an implementation of a Set called ArraySet.


● Won’t be implementing any interface (for now).
● Starting from basic implementation, we’ll add some “industrial
strength” features to the ArraySet like iteration, comparison, and
toString.
ArraySet<String> S = new ArraySet<>(); s = set()
S.add("Oakland"); s.add("Oakland")
S.add("Toronto"); s.add("Toronto")
S.add("Minneapolis"); s.add("Minneapolis")
S.add("Oakland"); // no effect s.add("Oakland") # no
S.add("Taipei"); effect
System.out.println(S.contains("Oakland")) s.add("Taipei")
; print("Oakland" in s)
$ java SetExample
true
$ python set_example.py
True
Goals

Starting point: A class ArraySet with the following methods:


● add(value): Add the value to the ArraySet if it is not already
present.
● contains(value): Checks to see if ArraySet contains the key.
● size(): Returns number of values.

For simplicity, I’ll ignore resizing.

The basic functionality is quite straightforward, so I’ll avoid live coding.


ArraySet (Basic Implementation)

public class ArraySet<T> { Array implementation of a


private T[] items; Set:
private int size; ● Use an array as the core
data structure.
public ArraySet() { ● contains(x): Checks to
items = (T[]) new see if x is in the
Object[100]; underlying array.
size = 0; ● add(x): Checks to see if
} x is in the underlying
... array, and if not, adds it.
}

"Unchecked cast" compiler warning


here. Nothing we can do about it.
ArraySet (Basic Implementation)

public boolean contains(T x) {


for (int i = 0; i < size; i +=
1) { public void add(T x) {
if (items[i].equals(x)) { if (!contains(x)) {
return true; items[size] =
} x;
} size += 1;
return false;
}
}
}

Can also throw an


We used items[i].equals(x), not IllegalArgumentException if you
items[i] == x. This actually want to disallow null. See the
matters; more details later in this videos for more details on
lecture. exceptions.
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable

The Enhanced Object Methods


• == vs. equals
For Loop • toString
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
The Enhanced For Loop

Java allows us to iterate through Lists and Sets using a convenient


shorthand syntax sometimes called the “foreach” or “enhanced for”
loop.

Set<Integer> javaset = new HashSet<>();


javaset.add(5);
javaset.add(23);
javaset.add(42);
for (int i : javaset) {
System.out.println(i);
}
The Enhanced For Loop

Java allows us to iterate through Lists and Sets using a convenient


shorthand syntax sometimes called the “foreach” or “enhanced for”
loop.
● This doesn’t work with our ArraySet.
● Let’s strip away the magic so we can build our own classes that
support this.

ArraySet<Integer> aset = new


ArraySet<>();
aset.add(5);
aset.add(23);
aset.add(42); $ javac IterationDemo
for (int i : aset) { error: for-each not applicable to expression
System.out.println(i); type
} for (int i : aset) {
^
required: array or java.lang.Iterable
found: ArraySet<Integer>
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable

iterator, next, Object Methods


• == vs. equals
hasNext • toString
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
Why Doesn’t the Enhanced For Loop Work?

The enhanced for loop works by first calling the .iterator method of
the object.
● This returns an object of type Iterator<Integer>.
● The Iterator interface has its own API for fetching values one-by-
one:
○ hasNext: Tells us whether there are more values.
○ next: gets the
ArraySet<Integer> next
aset value.
= new
ArraySet<>();
aset.add(5);
aset.add(23);
aset.add(42); What is
for (int i : aset) { missing?
System.out.println(i);
}
How Iteration Really Works

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
Set.java: public Iterator<E> iterator();
Suppose we have a Set<Integer> called javaset.
● In that case, we can iterate with either of the two equivalent pieces
of code.
● Left code is shorthand for right code.
Iterator<Integer> seer
= javaset.iterator();
for (int x : javaset) {
System.out.println(x); while (seer.hasNext()) {
} int x = seer.next();
System.out.println(x);
“Nice” iteration. }
“Ugly” iteration.
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.

javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.

$ java
IteratorDemo.java

javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
True

$ java
IteratorDemo.java

javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
5
$ java
IteratorDemo.java
5

javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
True
$ java
IteratorDemo.java
5

javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
23
$ java
IteratorDemo.java
5
23
javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
True
$ java
IteratorDemo.java
5
23
javaset: 5 23 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
42
$ java
IteratorDemo.java
5
23
javaset: 5 23 42 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
How Iterators Work

An alternate, uglier way to iterate through a Set is to use the


iterator() method.
False
$ java
IteratorDemo.java
5
23
javaset: 5 23 42 42

Iterator<Integer> seer
= javaset.iterator();
while (seer.hasNext()) {

System.out.println(seer.next());
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext
for ArraySet
iterator, next, • Iterable

hasNext for Object Methods


• == vs. equals
ArraySet • toString
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
The Secret of the Enhanced For Loop

The secret: The code on the left is just shorthand for the code on the
right. For code on right to compile, which checks does the compiler
need to do?
A. Does the Set interface have an iterator() method?
B. Does the Set interface have next/hasNext() methods?
C. Does the Iterator interface have an iterator method?
D. Does the Iterator interface have next/hasNext() methods?
Set<Integer> javaset = new
HashSet<Integer>();
Iterator<Integer> seer
for (int x : javaset) { = javaset.iterator();
System.out.println(x); while (seer.hasNext()) {
}
System.out.println(seer.next());
The Secret of the Enhanced For Loop

The secret: The code on the left is just shorthand for the code on the
right. For code on right to compile, which checks does the compiler
need to do?
A. Does the Set interface have an iterator() method?
B. Does the Set interface have next/hasNext() methods?
C. Does the Iterator interface have an iterator method?
D. Does the Iterator interface have next/hasNext() methods?
Set<Integer> javaset = new
HashSet<Integer>();
Iterator<Integer> seer
for (int x : javaset) { = javaset.iterator();
System.out.println(x); while (seer.hasNext()) {
}
System.out.println(seer.next());
Supporting Ugly Iteration in ArraySets

To support ugly iteration:


● Add an iterator() method to ArraySet that returns an
Iterator<T>.
● The Iterator<T> that we return should have a useful hasNext()
and next() method.
Iterator<T
>
public interface Iterator<T>
{
boolean hasNext(); Iterator<Integer> aseer
T next(); = aset.iterator();
}
while (aseer.hasNext()) {

System.out.println(aseer.next());
Completed ArraySet iterator Method

To support ugly iteration:


● Add an iterator() method to ArraySet that returns an
Iterator<T>.
● The Iterator<T> that we return should have a useful hasNext()
and next() method.

private class ArraySetIterator implements Iterator<T>


{
private int wizPos;
public ArraySetIterator() { wizPos = 0; }
public boolean hasNext() { return wizPos < size; }
public T next() {
T returnItem = items[wizPos];
public Iterator<T> iterator() {
wizPos += 1; return new
return returnItem; ArraySetIterator();
} }
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable
Object Methods
• == vs. equals
Iterable • toString
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
The Enhanced For Loop

Our code now supports “ugly” iteration, but enhanced for loop still
doesn’t work.

The problem: Java isn’t smart enough to realize that our ArraySet has
an iterator() method.
● Luckily there’s an interface for that.
ArraySet<Integer> aset = new
ArraySet<>();
aset.add(5);
aset.add(23);
aset.add(42); $ javac IterationDemo
for (int i : aset) { error: for-each not applicable to expression
System.out.println(i); type
} for (int i : aset) {
^
required: array or java.lang.Iterable
found: ArraySet<Integer>
For-each Iteration And ArraySets

To support the enhanced for loop, we need to make ArraySet


implement the Iterable interface.
● There are also some default methods in Iterable, not shown.

public interface Iterable<T> Iterable<T


{ >
Iterator<T> iterator();
}

public class ArraySet<T> implements


Iterable<T> { ArraySet<T>
...
public Iterator<T> iterator() { ... }
}
The Iterable Interface

By the way, this is how Set works as well.


● Source code for Iterable: Link, Set: Link, Collection: Link.

Iterable<T>

public interface Iterable<T>


{
Iterator<T> Collection<E
iterator(); ... >
public interface
} Collection<E> extends
Iterable<E> {
public Iterator<E> iterator();
} Set<E>
public interface Set<E> extends Collection<E> {
public Iterator<E> iterator();
}
Iteration Summary

To support the enhanced for loop:


● Add an iterator() method to your class that returns an
Iterator<T>.
● The Iterator<T> returned should have a useful hasNext() and
next() method.
● Add implements Iterable<T> to the line defining your class.

We’ll do this in the last part of project 1B.


Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable
Object Methods
• toString
toString • == vs. equals
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
Object Methods

All classes are hyponyms of Object.


● String toString()
Today
● boolean equals(Object obj)
● int hashCode() Coming later.
● Class<?> getClass()
● protected Object clone()
● protected void finalize()
● void notify()
● void notifyAll() Won’t discuss or use in 61B.
● void wait()
● void wait(long timeout)
● void wait(long timeout, int nanos)
toString()

The toString() method provides a string representation of an object.


● System.out.println(Object x) calls x.toString()
○ If you’re curious: println calls String.valueOf which calls toString

Set<Integer> javaset = new HashSet<>();


javaset.add(5);
javaset.add(23);
javaset.add(42);

System.out.println(javaset);
$ java
JavaSetPrintDemo
[5, 23, 42]
toString()

The toString() method provides a string representation of an object.


● System.out.println(Object x) calls x.toString()
● The implementation of toString() in Object is the the name of the
class, then an @ sign, then the memory location of the object.
○ See 61C for what the “memory location” really means.

ArraySet<Integer> aset = new


ArraySet<>();
aset.add(5);
aset.add(23);
aset.add(42);
$ java
System.out.println(aset); ArraySetPrintDemo
ArraySet@75412c2f
ArraySet toString

Let’s try implementing toString for ArraySet.


ArraySet toString

One approach is shown below.


● Warning: This code is slow. Intuition: Adding even a single character
to a string creates an entirely new string. Will discuss why at end of
course.

@Override Spoiler: It’s


because
public String toString() { Strings are
String returnString = "{"; “immutable
for (int i = 0; i < size; i += 1) ”.

{ keys[i] might not be a


string, but Java will
returnString += keys[i]; automatically call
returnString += ", "; toString so that you can
} add it to a string.
returnString += "}"; You can modify this code to avoid
return returnString; the extra comma at the end, if
you want.
}
ArraySet toString

Much faster approach is shown below.


● Intuition: Append operation for a StringBuilder is fast.
● See the videos for more details about StringBuilder.

@Override
public String toString() {
StringBuilder returnSB = new
StringBuilder("{");
for (int i = 0; i < size; i += 1) {
returnSB.append(items[i]);
returnSB.append(", ");
}
returnSB.append("}");
return returnSB.toString();
}
Today’s Goal: ArraySet
Iteration
• The Enhanced For Loop
• iterator, next, hasNext
• iterator, next, hasNext for
ArraySet
• Iterable
Object Methods
• toString
== vs. equals • == vs. equals
• Better toString (Bonus)
Lecture 10, CS61B, Fall 2024 • .of (Bonus)
Object Methods

All classes are hyponyms of Object.


● String toString()
Coming in another lecture soon.
● boolean equals(Object obj)
● int hashCode() Coming later.
● Class<?> getClass()
● protected Object clone()
● protected void finalize()
● void notify()
● void notifyAll() Won’t discuss or use in 61B.
● void wait()
● void wait(long timeout)
● void wait(long timeout, int nanos)
Equals vs. ==

As mentioned in an offhand manner previously, == and .equals() behave


differently.
● == compares the bits. For references, == means “referencing the same
object.”
Set<Integer> javaset = Set.of(5, 23, 42);
Set<Integer> javaset2 = Set.of(5, 23,
42);
System.out.println(javaset == javaset2);
$ java
EqualsDemo
False
Equals vs. ==

As mentioned in an offhand manner previously, == and .equals() behave


differently.
● == compares the bits. For references, == means “referencing the same
object.”
Set<Integer> javaset = Set.of(5, 23, 42);
Set<Integer> javaset2 = Set.of(5, 23,
42);
System.out.println(javaset.equals(javaset
2)); $ java
EqualsDemo
True

To test equality in the sense we usually mean it, use:


● .equals for classes. Requires writing a .equals method for your
classes.
○ Default implementation of .equals uses == (probably not what you
this: Address of Current Object

this is a reference to the current object. Example from lecture 2:

public Dog maxDog(Dog uddaDog) {


if (size > uddaDog.size) {
return this;
}
return uddaDog;
}
this: Address of Current Object

Naturally, can also use this to access your own instance variables or
methods.
● Unlike Python, where self is mandatory, using this is not
mandatory.
● Two code snippets below are exactly identical in behavior.

public Dog maxDog(Dog o) { public Dog maxDog(Dog o) {


if (this.size > o.size) if (size > o.size) {
{ return this;
return this; }
} return o;
return o; }
}
this

Naturally, can also use this to access your own instance variables or
methods.
● Unlike Python, where self is mandatory, using this is not
mandatory.
● If there’s ever a name conflict where a local variable has the same
name as an instance variable (left), you must use this if you want
to access the instance variable.
public Dog(int size) { public Dog(int s) {
size = size; size = s;
} Does nothing!
} Works correctly!

public Dog(int size) { public Dog(int s) {


this.size = size; this.size = s;
} Works correctly!
} Works correctly!
The Default Implementation of Equals

Below, we see the actual code for the default equals method in
Object.java.
● Code available here if you want to poke around:
https://github.com/openjdk/jdk17/blob/master/src/java.base/share/cl
asses/java/lang/Object.java#L162

public class Object {

...

public boolean equals(Object obj)


{
return (this == obj);
}
}
The Default Implementation of Equals

ArraySet<Integer> aset = new


ArraySet<>();
aset.add(5);
aset.add(23);
aset.add(42);

System.out.println(aset);
$ java
EqualsDemo
ArraySet<Integer> aset2 = new False
ArraySet<>();
aset2.add(5); Returns false because
the default
aset2.add(23); implementation of equals
aset2.add(42); just uses ==.

System.out.println(aset.equals(aset2));
instanceOf Demo

The instanceof keyword is very powerful in Java.


● Checks to see if o’s dynamic type is Dog (or one of its subtypes).
If no, returns false.
● If yes, returns true and casts o into a variable of static type Dog called
uddaDog.
● Works correctly, even if o is null.
@Override
public boolean equals(Object o) {
if (o instanceof Dog uddaDog) {
return this.size == uddaDog.size;
}
return false;
}

Let’s try to write ArraySet’s equals method.


ArraySet equals

The code below is pretty close to what a standard equals method looks
like.
@Override
public boolean equals(Object other) { Technically a raw type
if (this == other) { return true; } without a type
placeholder like
ArraySet<T>, but
if (other instanceof ArraySet otherSet) { don't worry about it.
if (this.size != otherSet.size) { return false; }
for (T x : this) {
if (!otherSet.contains(x)) {
return false;
}
}
return true;
}
return false;
}
ArraySet equals

The code below is pretty close to what a standard equals method looks
like.
@Override
public boolean equals(Object other) { Doesn't affect
if (this == other) { return true; } correctness, but saves
us time if this and
other reference the
if (other instanceof ArraySet otherSet) { same object.
if (this.size != otherSet.size) { return false; }
for (T x : this) {
if (!otherSet.contains(x)) {
return false;
}
}
return true;
}
return false;
}
Summary

We built our own Array based Set implementation.

To make it more industrial strength we:


● Added an exception if a user tried to add null to the set. (See
videos.)
○ There are other ways to deal with nulls. Our choice was
arguably bad.
● Added support for “ugly” then “nice” iteration.
○ Ugly iteration: Creating a subclass with next and hasNext
methods.
○ Nice iteration: Declaring that ArraySet implements Iterable.
● Added a toString() method.
○ Beware of String concatenation.
● Added an equals(Object) method.

You might also like