Image source: https://refactoring.guru/
Joe
I have a collection of elements I don't know much about; but I know that there should be a "next element".
I want to access and traverse the collection's elements without exposing its implementation.
Intent: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying implementation
...all term long...
for (Item next : collection) {
// do something with next
}
...where collection was e.g. an ArrayList, LinkedList, HashSet of objects of type Item
Iterator<Item> itr = collection.iterator();
while (itr.hasNext()) {
Item nextItem = itr.next();
// do something with nextItem
}
for (Item next : collection) {
if ("Chickpeas".equals(next.getName())) {
collection.remove(next);
}
}
This doesn't work!
Iterator<Item> iterator = collection.iterator();
while (iterator.hasNext()) {
Item next = iterator.next();
if ("Chickpeas".equals(next.getName())) {
iterator.remove();
}
}
But this does!
Iterator<Item> itr = collection.iterator();
while (itr.hasNext()) {
Item nextItem = itr.next();
// do something with nextItem
}
Iterator<E> iterator();
boolean hasNext();
E next();
returns new ArrayListIterator<E>()
returns new LinkedListIterator<E>()
returns new HashSetIterator<E>()
ArrayListIterator<E>
LinkedListIterator<E>
HashSetIterator<E>
Iterable<E>
Iterator<E> iterator()
<<interface>>
Iterator<E>
boolean hasNext()
E next()
void remove()
<<interface>>
Collection
<<interface>>
List<E>
<<interface>>
LinkedList<E>
Iterator<E> iterator()
ArrayList<E>
Iterator<E> iterator()
HashSet<E>
Iterator<E> iterator()
Set<E>
<<interface>>
for (Item next : collection) {
// do something with next
}
Let's look at the lecture ticket as an example...
Thing doll = new Thing("Doll");
Thing puppy = new Thing("Puppy");
Thing marble = new Thing("Marble");
ThingCollection myThings = new ThingCollection();
myThings.add(doll);
myThings.add(puppy);
myThings.add(marble);
for(Thing thing : myThings) {
thing.display();
}
Not compiling:
foreach not applicable
to type 'ThingCollection'
public class Thing {
private String name;
public Thing(String name) {
this.name = name;
}
public void display() {
System.out.println("Behold,
the beautiful " + name);
}
}
Your code
Thing
public class ThingCollection {
private ArrayList<Thing> things = new ArrayList<>();
public void add(Thing thing) {
System.out.println("Ooh --- I have a new " + thing);
things.add(thing);
}
}
ThingCollection
ThingCollection
Thing
ThingCollection
things.iterator()