CS计算机代考程序代写 compiler Java data structure python CS61B: 2021

CS61B: 2021
Lecture 11: The End of Java ● Lists and Sets
● Exceptions
● Iteration
● toString and Equals
datastructur.es

Lists and Sets in Java
datastructur.es

Lists
In lecture, we’ve build two types of lists: ALists and SLLists. ● Similar to Python lists.
List61B L = new AList<>(); L.addLast(5);
L.addLast(10);
L.addLast(15);
L.print();
L = [] L.append(3) L.append(4) L.append(5) print(L)
$ java ListExample
3 45
$ python list_example.py [3 4 5]
Note: We saw this in an earlier lecture, but repeated here for narrative flow.
datastructur.es

Lists in Real Java Code
We built a list from scratch, but Java provides a built-in List interface and several implementations, e.g. ArrayList.
List61B L = new AList<>(); L.addLast(5);
L.addLast(10);
L.addLast(15);
L.print();
java.util.List L = new java.util.ArrayList<>(); L.add(5);
L.add(10);
L.add(15);
System.out.println(L);
datastructur.es

Lists in Real Java Code
By including “import java.util.List” and “import java.util.ArrayList” at the top of the file, we can make our code more compact.
import java.util.List; import java.util.ArrayList;
public class SimpleBuiltInListExample { public static void main(String[] args) {
List L = new ArrayList<>(); L.add(5);
L.add(10);
L.add(15);
System.out.println(L); }
If we import, we can use the “simple name” (ArrayList) as opposed to the longer “canonical name” (java.util.ArrayList).
}
datas
tructur.es

Sets in Java and Python
Another handy data structure is the set.
● Stores a set of values with no duplicates. Has no sense of order.
Set S = new HashSet<>(); S.add(“Tokyo”); S.add(“Beijing”); S.add(“Lagos”);
S.add(“São Paulo”); System.out.println(S.contains(“Tokyo”));
s = set() s.add(“Tokyo”) s.add(“Beijing”) s.add(“Lagos”) s.add(“São Paulo”) print(“Tokyo” in s)
$ java SetExample
true
$ python set_example.py
True
datastructur.es

ArraySet
Today we’re going to write our own Set called ArraySet.
● Won’t be implementing any specific interface (for now).
ArraySet S = new ArraySet<>(); S.add(“Tokyo”);
S.add(“Beijing”);
S.add(“Lagos”);
S.add(“São Paulo”); System.out.println(S.contains(“Tokyo”)); System.out.println(S.size());
datastructur.es

Goals
Goal 1: Create 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.
Ok to ignore resizing for this exercise.
● In lecture, I’ll just give away the answer, but you might find implementing it useful. See DIY folder in the lectureCode repo for starter code.
datastructur.es

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

ArraySet (Basic Implementation)
public boolean contains(T x) {
for (int i = 0; i < size; i += 1) { if (items[i].equals(x)) { return true; } } return false; } public void add(T x) { if (!contains(x)) { items[size] = x; size += 1; } } datastructur.es Using An ArraySet Generic type variables public class ArraySet { private T[] items; private int size;
public ArraySet() {
items = (T[]) new Object[100]; size = 0;
}
… }
Actual type arguments
ArraySet S = new ArraySet<>(); S.add(“horse”);
S.add(“fish”);
datastruct
ur.es

Exceptions
datastructur.es

Exceptions
Basic idea:
● When something goes really wrong, break the normal flow of control.
● So far, we’ve only seen implicit exceptions, like the one below.
public static void main(String[] args) { ArraySet s = new ArraySet<>(); s.add(null);
s.add(“horse”);
}
$ java ExceptionDemo
Exception in thread “main”
java.lang.NullPointerException
at ArraySet.contains(ArraySet.java:16)
at ArraySet.add(ArraySet.java:26)
at ArraySet.main(ArraySet.java:40)
datastructur.es

Explicit Exceptions
We can also throw our own exceptions using the throw keyword. More on
● Can provide more informative message to a user.
● Can provide more information to code that “catches” the exception. course.
“catching” at end of the
public void add(T x) { if (x == null) {
throw new IllegalArgumentException(“Cannot add null!”); }

}
$ java ExceptionDemo
Exception in thread “main”
java.lang.IllegalArgumentException: Cannot add null!
at ArraySet.add(ArraySet.java:27)
at ArraySet.main(ArraySet.java:42)
datastructur.es

Explicit Exceptions
Arguably this is a bad exception.
● Our code now crashes when someone tries to add a null.
● Other fixes:
○ Ignore nulls.
○ Fix contains so that it doesn’t crash if items[i] is null.
public void add(T x) { if (x == null) {
throw new IllegalArgumentException(“Cannot add null!”); }

}
datastructur.es

Iteration
datastructur.es

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 javaset = new HashSet<>(); javaset.add(5);
javaset.add(23);
javaset.add(42);
for (int i : javaset) { System.out.println(i);
}
datastructur.es

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 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 type
System.out.println(i); for (int i : S) { ^
}
required: array or java.lang.Iterable
found: ArraySet
datastructur.es

How Iteration Really Works
An alternate, uglier way to iterate through a List is to use the iterator() method.
“Nice” iteration.
Set.java:
public Iterator iterator();
Set javaset = new HashSet();

Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
Set javaset = new HashSet();

for (int x : javaset) {
System.out.println(x); }
“Ugly” iteration.
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
$ java IteratorDemo.java
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
True
$ java IteratorDemo.java
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
5
$ java IteratorDemo.java
5
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
True
$ java IteratorDemo.java
5
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
23
$ java IteratorDemo.java
5
23
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
True
$ java IteratorDemo.java
5
23
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
42
$ java IteratorDemo.java
5
23
42
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

How Iterators Work
An alternate, uglier way to iterate through a List is to use the iterator() method.
False
$ java IteratorDemo.java
5
23
42
5
23
42
javaset:
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
datastructur.es

The Secret of the Enhanced For Loop yellkey.com/art
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?
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
for (int x : javaset) { System.out.println(x);
}
datastructur
Set javaset = new HashSet();
.es

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?
Iterator seer
= javaset.iterator();
while (seer.hasNext()) { System.out.println(seer.next());
}
for (int x : javaset) { System.out.println(x);
}
datastructur
Set javaset = new HashSet();
.es

Supporting Ugly Iteration in ArraySets
To support ugly iteration:
● Add an iterator() method to ArraySet that returns an Iterator.
● The Iterator that we return should have a useful hasNext() and
next() method.
Iterator
Iterator aseer = aset.iterator();
while (aseer.hasNext()) { System.out.println(aseer.next());
}
datastructur
public interface Iterator { boolean hasNext();
T next(); }
.es

Completed ArraySet iterator Method
To support ugly iteration:
● Add an iterator() method to ArraySet that returns an Iterator.
● The Iterator that we return should have a useful hasNext() and
next() method.
datastructur.es
private class ArraySetIterator implements Iterator { private int wizPos;
public ArraySetIterator() { wizPos = 0; }
public boolean hasNext() { return wizPos < size; } public T next() { T returnItem = items[wizPos]; wizPos += 1; return returnItem; } } public Iterator iterator() { return new ArraySetIterator();
}

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 aset = new ArraySet<>(); aset.add(5);
aset.add(23);
aset.add(42);
for (int i : aset) { …
}
$ javac IterationDemo
error: for-each not applicable to expression type
for (int i : aset) {
^
required: array or java.lang.Iterable
found: ArraySet
datastructur.es

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 { Iterator iterator();
}
Iterable
public class ArraySet implements Iterable { …
public Iterator iterator() { … } }
ArraySet
datastructur.es

The Iterable Interface
By the way, this is how Set works as well.
● Source code for Iterable: Link, Set: Link, Collection: Link.
Iterable
public interface Iterable { Iterator iterator(); …
}
Collection
public interface Collection extends Iterable { public Iterator iterator();
}
Set
public interface Set extends Collection { public Iterator iterator();
}
datastructur.es

Iteration Summary
To support the enhanced for loop:
● Add an iterator() method to your class that returns an Iterator.
● The Iterator returned should have a useful hasNext() and next()
method.
● Add implements Iterable to the line defining your class.
Part 5 of HW1 gives you a chance to try this out yourself.
datastructur.es

Object Methods: Equals and toString()
datastructur.es

Objects
All classes are hyponyms of Object.
● String toString()
● boolean equals(Object obj)
● Class getClass()
● int hashCode()
● protected Objectclone()
● protected void finalize()
● void notify()
● void notifyAll()
● void wait()
● void wait(long timeout)
● void wait(long timeout, int nanos)
Very important, but won’t discuss for a few weeks.
Won’t discuss or use in 61B.
datastructur.es

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 javaset = new HashSet<>(); javaset.add(5);
javaset.add(23);
javaset.add(42);
System.out.println(javaset);
$ java JavaSetPrintDemo
[5, 23, 42]
datastructur.es

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 aset = new ArraySet<>(); aset.add(5);
aset.add(23);
aset.add(42);
System.out.println(aset);
$ java ArraySetPrintDemo
ArraySet@75412c2f
datastructur.es

ArraySet toString
Let’s try implementing toString for ArraySet.
datastructur.es

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.
Spoiler: It’s because Strings are “immutable”.
@Override
public String toString() {
String returnString = “{“;
for (int i = 0; i < size; i += 1) { returnString += keys[i]; returnString += ", "; } returnString += "}"; return returnString; } datastructur.es ArraySet toString Much faster approach is shown below. ● Intuition: Append operation for a StringBuilder is fast. @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(); } datastructur.es Objects All classes are hyponyms of Object. ● String toString() ● boolean equals(Object obj) ● Class getClass()
● int hashCode()
● protected Objectclone()
● protected void finalize()
● void notify()
● void notifyAll()
● void wait()
● void wait(long timeout)
● void wait(long timeout, int nanos)
Very important, but won’t discuss for a few weeks.
Won’t discuss or use in 61B.
datastructur.es

Equals vs. ==
As mentioned in an offhand manner previously, == and .equals() behave differently. ● == compares the bits. For references, == means “referencing the same object.”
Set javaset = Set.of(5, 23, 42); Set javaset2 = Set.of(5, 23, 42); System.out.println(javaset == javaset2);
$ java EqualsDemo
False
datastructur.es

Equals vs. ==
As mentioned in an offhand manner previously, == and .equals() behave differently. ● == compares the bits. For references, == means “referencing the same object.”
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 want).
● BTW: Use Arrays.equal or Arrays.deepEquals for arrays.
Set javaset = Set.of(5, 23, 42); Set javaset2 = Set.of(5, 23, 42); System.out.println(javaset.equals(javaset2));
$ java EqualsDemo
True
datastructur.es

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

ArraySet equals
Let’s try implementing equals for ArraySet.
datastructur.es

ArraySet equals
The implementation below is a good start, but fails if o is null or another class.
@Override
public boolean equals(Object o) {
ArraySet other = (ArraySet) o;
if (this.size() != other.size()) { return false; }
for (T item : this) {
if (!other.contains(item)) {
return false; }
}
return true;
}
datastructur.es

ArraySet equals
The implementation below is much better, but we can speed things up.
@Override
public boolean equals(Object o) {
if (o == null) { return false; }
if (this.getClass() != o.getClass()) { return false; } ArraySet other = (ArraySet) o;
if (this.size() != other.size()) { return false; }
for (T item : this) {
if (!other.contains(item)) {
return false; }
}
return true;
}
datastructur.es

ArraySet equals
The code below is pretty close to what a standard equals method looks like.
@Override
public boolean equals(Object o) {
if (o == null) { return false; }
if (this == o) { return true; } // optimization
if (this.getClass() != o.getClass()) { return false; } ArraySet other = (ArraySet) o;
if (this.size() != other.size()) { return false; }
for (T item : this) {
if (!other.contains(item)) {
return false; }
}
return true;
}
datastructur.es

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.
○ 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.
○ Make sure to deal with null and non-ArraySet arguments!
○ Used getClass to check the class of the passed object. Use sparingly.
datastructur.es

Even Better toString and ArraySet.of
(Extra)
datastructur.es

Citations
Seer:
http://www.clipartoday.com/_thumbs/022/Fantasy/astrology_crystal_190660_ tnb.png
Edge of the world:
The Edge of The World
datastructur.es

datastructur.es