Separate concepts:
* C++ iterators, itself made up of different concepts - input iterators: a kind of input pipe; - output iterators: an output pipe; - bidirectional; - random: not really an iterator at all; - often requires pairs to operate over a range
* Java iterators, and the fairly closely related concept of .NET's IEnumerable, IEnumerator and associated generic types
* Sugared iteration syntax (as opposed to imperative explicit iteration syntax)
* Iterators as read-only containers
Even with Java containers, iterators are not recommended as a poor-man's collection - rather, one should derive from AbstractCollection so that you can at least provide size() as well as the iterator itself.
But iterators as implemented in .NET, IEnumerable and IEnumerator, are more interesting as they represent a kind of lazily-calculated monadic stream of values, which can be filtered etc. If you condemn iterators, you're also throwing away LINQ.
Seems to me that he primarily dislikes the explicit iteration syntax, likes the sugared syntax, but to leap from there to condemning iterators ignores the question as to how the sugared syntax ought to be implemented. It's not clear that iterators aren't an excellent way to implement the sugared syntax under the hood for at least a subset of container types, not least because of the benefits of something like LINQ when applied to a bare-bones container that doesn't even supply a size() operation (think: infinite lists).
C++ iterators, being a jumble of related concepts, have separate plus and minus points. They're often too verbose and introduce too many moving pieces when simply dealing with a collection - you have to keep track of both the beginning and the end of your range, which is often relevant in an algorithm implementation, but rarely in use, which is usually just an iteration over a transformed or filtered collection.