12. Inheritance IV: Iterators, Object Methods

12.1 Lists and Sets in Java

list

java 提供了 built-in 的 List interface 和一些实现,比如 ArrayList.

import java.util.List;
import java.util.ArrayList;

public class Example {
    public static void main(String[] args) {
        List<Integer> L = new ArrayList<>();
        L.add(5);
        L.add(10);
        System.out.println(L);
    }
}

set

java 提供了 built-in 的 Set interface 和一些实现,比如 HashSet.

import java.util.Set;
import java.util.HashSet;

Set<String> s = new HashSet<>();
s.add("Tokyo");
s.add("Lagos");
System.out.println(s.contains("Tokyo")); // true

12.2 Exceptions

java 抛出异常语法:

throw new ExceptionObject(parameter1, ...)

比如在 x==null 时抛出异常:

public void add(T x) {
    if (x == null) {
        throw new IllegalArgumentException("can't add null");
    }
    if (contains(x)) {
        return;
    }
    items[size] = x;
    size += 1;
}

12.3 Iteration

Enhanced For Loop

Set<String> s = new HashSet<>();
...
for (String city : s) {
    ...
}

等价于

Set<String> s = new HashSet<>();
...
Iterator<String> seer = s.iterator();
while (seer.hasNext()) {
    String city = seer.next();
    ...
}

Implementing Iterators

首先 class 必须 implements Iterable interface, Iterable interface 提供了:

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

接着 需要在内部实现 Iterator interface.

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

例子如下:

import java.util.Iterator;

public class ArraySet<T> implements Iterable<T> {
    private T[] items;
    private int size; // the next item to be added will be at position size

    public ArraySet() {
        items = (T[]) new Object[100];
        size = 0;
    }

    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 (x == null) {
            throw new IllegalArgumentException("can't add null");
        }
        if (contains(x)) {
            return;
        }
        items[size] = x;
        size += 1;
    }

    public int size() {
        return size;
    }

    public Iterator<T> iterator() {
        return new ArraySetIterator();
    }

    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];
            wizPos += 1;
            return returnItem;
        }
    }

    public static void main(String[] args) {
        ArraySet<Integer> aset = new ArraySet<>();
        aset.add(5);
        aset.add(23);
        aset.add(42);

        //iteration
        for (int i : aset) {
            System.out.println(i);
        }
    }

}

12.4 Object Methods

所有的 class 都会从 object 中继承下面的 methods:

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)

这一章只会关注前两个 toString()equals().

toString()

System.out.println(dog) 实际上做的事是:

String s = dog.toString()
System.out.println(s)

通过 override toString()equals()可以达到我们 class 想要的效果。比如在 ArraySet 中重写 toString:

@Override
public String toString() {
        StringBuilder returnSB = new StringBuilder("{");
        for (int i = 0; i < size - 1; i += 1) {
            returnSB.append(items[i].toString());
            returnSB.append(", ");
        }
        returnSB.append(items[size - 1]);
        returnSB.append("}");
        return returnSB.toString();
    }

equals()

重写 equals() 可以自定义==比较的内容,class ArraySet 的 equal 实现:

@Override
public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null) { // x.equals(null) 必须是 false
            return false;
        }
        if (other.getClass() != this.getClass()) {
            return false;
        }
        ArraySet<T> o = (ArraySet<T>) other;
        if (o.size() != this.size()) {
            return false;
        }
        for (T item : this) {
            if (!o.contains(item)) {
                return false;
            }
        }
        return true;
    }

2025 lecture video 中的实现用了 instanceof:

public boolean equals(Object o) {
    if (o instanceof Dog uddaDog) {
        return this.size == uddaDog.size;
    }
    return false;
}