I was recently taking the UCB CS70B course and following the code example of iterator in the lecture video: https://www.youtube.com/watch?v=AKnMv0ootkg&list=PL8FaHk7qbOD4vPE_Bd8QagarKi3kPw8rB&index=5
I followed the video to write the following Java code:
import java.util.*;
public class ArraySet<T> implements Iterable<T>{
private T[] items;
private int size;
public ArraySet() {
items=(T[]) new Object[100];
size=0;
}
/* Returns true if this map contains a mapping for the specified key.
*/
public boolean contains(T x) {
for (int i=0;i<size;i+=1){
if (items[i]==null){
if (x==null){
return true;
}
}
if (x.equals(items[i])){
return true;
}
}
return false;
}
/* Associates the specified value with the specified key in this map.
Throws an IllegalArgumentException if the key is null. */
public void add(T x) {
if (x==null){
throw new IllegalArgumentException("Cannot add null to ArraySet");
}
if (contains(x)){
return;
}
items[size]=x;
size+=1;
}
/* Returns the number of key-value mappings in this map. */
public int size() {
return size;
}
//returns an iterator into ME
@Override
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;
}
/*
@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();
}
*/
@Override
public String toString(){
List<String> listOfItems=new ArrayList<>();
for (T x:this){
listOfItems.add(x.toString());
}
String.join(",",listOfItems);
return "{"+String.join(",",listOfItems);
}
@Override
public boolean equals(Object o){//overriding equals always input Object
if (o instanceof ArraySet oas){
if (oas.size!=size){
return false;
}
for (T x:this){
if (!oas.contains(x)){
return false;
}
}
}
return true;
}
public static<Glerp> ArraySet<Glerp> of(Glerp...stuff){
ArraySet<Glerp> returnSet=new ArraySet<Glerp>();
for (Glerp x: stuff){
returnSet.add(x);
}
return returnSet;
}
}
public static void main(String[] args) {
ArraySet<String> s = new ArraySet<>();
s.add("horse");
s.add("fish");
s.add("house");
s.add("fish");
System.out.println(s.contains("horse"));
System.out.println(s.size());
ArraySet<Integer> aset=new ArraySet<>();
aset.add(5);
aset.add(55);
aset.add(789);
for (int i:aset){
System.out.println(i);
}
}
In this code, I got public class ArraySet<T> implements Iterable<T>
and wrote the method public Iterator<T> iterator()
and private class ArraySetIterator implements Iterator<T>
, just like the video has done. But when I write toString()
method and equals()
method, the instructor wrote for (T x:this)
and works fine, but my code in IDEA showed “Foreach not applicable to type ‘ArraySet.ArraySetIterator'” for both for (T x:this)
and IDEA suggests me to change to for (ArraySetIterator it = this; it.hasNext(); )
. So I am asking why this is happening and why the instructor could do it perfectly but mine couldn’t?
I googled around and asked ChatGPT but none of them provided answers as if this should not happen at all. All I found was this:foreach not applicable to expression type
which did not implements iterable and override Iterator