Exceptions, Iterators, Iterables
Author: Brandon Lee

Lecture Code

Code from this lecture available at

https://github.com/Berkeley-CS61B/lectureCode-fa20/tree/master/inheritance4.

Check-in Exercise

Linked here.

Exceptions

Most likely you have encountered an exception in your code such as a NullPointerException or an IndexOutOfBoundsException. Now we will learn about how we can “throw” exceptions ourselves, and also handle thrown exceptions. Here is an example of an exception that we throw:

throw new RuntimeException("For no reason.");

Note: Try/Catch is out of scope for now!

Throwing exceptions is useful to notify your user of something wrong they have done. On the other hand, we can also “catch” exceptions that happen in our code! Here is an example:

try {
    dog.run()
} catch (Exception e) {
    System.out.println("Tried to run: " + e);
}
System.out.println("Hello World!");

There are a few key things to note. Firstly, the entirety of the try section is run until/if there is an exception thrown. If there never is an exception, the entire catch block is skipped. If there is an exception, the code immediately jumps into the catch block with the corresponding exception, and executes from there.

Iterators and Iterables

These two words are very closely related, but have two different meanings that are often easy to confuse. The first thing to know is that these are both Java interfaces, with different methods that need to be implemented. Here is a simplified interface for Iterator:

public interface Iterator<T> {
  boolean hasNext();
  T next();
}

Here is a simplified interface for Iterable:

public interface Iterable<T> {
    Iterator<T> iterator();
}

Notice that in order for an object (for example an ArrayList or LinkedList) to be iterable, it must include a method that returns an iterator. The iterator is the object that iterates over an iterable object. Keep this relationship and distinction in mind as you work with these two interfaces.

toString

The toString() method returns a string representation of objects.

== vs .equals

We have two concepts of equality in Java- “==” and the “.equals()” method. The key difference is that when using ==, we are checking if two objects have the same address in memory (that they point to the same object). On the other hand, .equals() is a method that can be overridden by a class and can be used to define some custom way of determining equality.

For example, say we wanted to check if two stones are equal:

public class Stone{
  public Stone(int weight){...}
}
Stone s = new Stone(100);
Stone r = new Stone(100);

If we want to consider s and r equal because they have the same weight. If we do check equality using ==, these Stones would not be considered equal because they do not have the same memory address.

On the other hand, if you override the equals method of Stone as follows

public boolean equals(Object o){
  return this.weight == ((Stone) o).weight
}

We would have that the stones would be considered equal because they have the same weight.

Past Exam Questions

Spring2018MT2Q7