The code below is throwaway, a failed idea to get an Enumeration to work in the new foreach loop, however I'd like to get it compiling since I keep running into an issue with generics and wild cards. For whatever reason I cannot see how to fix it.
So, what changes need to be made to make this compile?
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Main
{
private ZipFile zipFile;
public Set<String> entries()
{
final Set<String> names;
final Enumeration<? extends ZipEntry> enumeration;
final IterableEnumeration<? extends ZipEntry> iteratable;
names = new HashSet<String>();
// zipFile.entries() returns "Enumeration<? extends ZipEntry>"
enumeration = zipFile.entries();
// this line won't compile
iteratable = new IterableEnumeration<? extends ZipEntry>(enumeration);
for(final ZipEntry entry : iteratable)
{
if(!(entry.isDirectory()))
{
names.add(entry.getName());
}
}
return (names);
}
}
class IterableEnumeration<T>
implements Iterable<T>
{
private final Enumeration<T> enumeration;
public IterableEnumeration(final Enumeration<T> e)
{
enumeration = e;
}
public Iterator<T> iterator()
{
final EnumerationIterator<T> iterator;
// yeah cannot do this since an Iterable is supposed to work multiple times on the same object and Enumeration is descructive...
iterator = new EnumerationIterator<T>(enumeration);
return (iterator);
}
}
class EnumerationIterator<T>
implements Iterator<T>
{
private final Enumeration<T> enumeration;
public EnumerationIterator(final Enumeration<T> e)
{
enumeration = e;
}
public boolean hasNext()
{
return (enumeration.hasMoreElements());
}
public T next()
{
return (enumeration.nextElement());
}
public void remove()
{
throw new UnsupportedOperationException("Cannt remove via an Enumeration");
}
}
The error is:
Main.java:26: unexpected type
found : ? extends java.util.zip.ZipEntry
required: class or interface without bounds
iteratable = new IterableEnumeration<? extends ZipEntry>(enumeration);
^
1 error
You cannot specify a wildcard when constructing a parameterized type. This is the correct syntax:
iteratable = new IterableEnumeration<ZipEntry>(enumeration);
As you noted, there's difficulty in implementing Iterable
with an Enumeration
because Enumeration
is one-time use, while code can rely on Iterable
to create as many fresh Iterator
objects as it wishes. You could safely use this in enhanced for-loops, but it would be unsafe to pass such an Iterable
to any other method.
Oscar is right, the above change is not sufficient. I overlooked the fact that the underlying enumeration
is "? extends ZipEntry
". In addition, make the following changes:
class IterableEnumeration<T>
implements Iterable<T>
{
private final Enumeration<? extends T> enumeration;
public IterableEnumeration(final Enumeration<? extends T> e)
{
enumeration = e;
}
...
and
class EnumerationIterator<T>
implements Iterator<T>
{
private final Enumeration<? extends T> enumeration;
public EnumerationIterator(final Enumeration<? extends T> e)
{
enumeration = e;
}
...
These changes basically mean, "IterableEnumeration<T>
can collaborate with an Enumeration
of any sub-type of T
."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With