It looks like you're confused. a -= 2
doesn't remove element 2. If it could, then a
would, by definition, be a mutable set, since you're changing it. a -= 2
creates a brand new set that looks like the old one, and assigns it to the variable a
. How is ite
supposed to magically know that this has happened?
The answer is, it can't--not if it's already started running. That is, in fact, the whole point of using immutable data structures. If someone else decides the world looks differently now, you aren't thrown into confusion--you keep working on your old copy that looks the same as ever.
But if the iterator hasn't already been used, and you just want a handy label that means "get the iterator of a", you can
var a = Set(1,2,3,4,5)
val ite = () => a.iterator
a -= 2
ite().foreach(println) // Prints 5,1,3,4 or the like--no 2
Here, ite
is not a variable, it's a function that happens to be a closure of a.iterator
. It calls a.iterator
every time you use it, so it's always up to date (at least initially). You could also create a lazy iterator that doesn't actually pick which version a
to use until it's needed:
var a = Set(1,2,3,4,5)
lazy val ite = a.iterator // Not a.iterator now, but will be when we need it!
a -= 2
ite.foreach(println) // Need it now--so we'll get 5,1,3,4
Note that in this case, if you call a method that takes an iterator, ite will be set when it is passed to the function. The previous version--that takes a function returning an iterator--will only create the iterator once.
Now, you might want an iterator that can deal with deleted entries by looking at the current value of a
. You can do that, too, but it's easier to implement if the deleted results come back None
and the undeleted ones come back Some(x)
:
var a = Set(1,2,3,4,5)
val ite = new Iterator[Option[Int]] {
private val it = a.iterator
def hasNext = it.hasNext
def next = {
val i = it.next
if (a(i)) Some(i) else None
}
}
a -= 2
ite.foreach(println) // Some(5),Some(1),None,Some(3),Some(4)
(Otherwise, you'd have to cache values, since hasNext
in this iterator would need to call next
in the a
's iterator so it could check if that element still existed.)
Anyway, there are lots of options, but you need to decide which sensible thing to do that it is that you really want to do.