Converting Enumeration to Iterator
-
20-08-2019 - |
Question
I have the following implicit conversion for java.util.Enumerations
implicit def enumerationIterator[A](e : Enumeration[A]) : Iterator[A] = {
new Iterator[A] {
def hasNext = e.hasMoreElements
def next = e.nextElement
def remove = throw new UnsupportedOperationException()
}
}
Unfortunately it does not work for ZipFile.entries
because it returns an Enumeration<? extends ZipEntry>
(see related question) and Scalac keeps telling me
type mismatch; found : java.util.Iterator[?0]
where type ?0 <: java.util.zip.ZipEntry
required: Iterator[?]
I can't figure out how to make the conversation work in sth. like
List.fromIterator(new ZipFile(z).entries))
Solution
List.fromIterator expects a scala.Iterator but your implicit is returning a java.util.Iterator.
This works
import java.util.Enumeration
implicit def enum2Iterator[A](e : Enumeration[A]) = new Iterator[A] {
def next = e.nextElement
def hasNext = e.hasMoreElements
}
import java.util.zip.{ZipFile, ZipEntry}
val l = List.fromIterator(new ZipFile(null:java.io.File).entries)
Adding one import at the top prevents compilation
import java.util.Iterator
There's been some discussion about unifying Scala and Java in 2.8 by just using java.util.Iterator. On the downside, Java's Iterator has a remove method which makes no sense for Scala's immutable collections. UnsupportedOperationException? Blech! On the plus side that makes stuff like this error go away.
Edit: I've added a Trac issue that the error message would have been clearer had it said "required: scala.Iterator[?]" https://lampsvn.epfl.ch/trac/scala/ticket/2102
OTHER TIPS
As far as I know, Enumeration in Scala 2.7.x has an "elements" method and Scala 2.8.0 has an "iterator" method returing an Iterator. Why not use them?
Oh, never mind, never mind. Java's enumeration.