So I am attempting to create a LinkedHashedDictionary's Iterator member for a homework assignment, however I am having multiple issues regarding its types.
Iterator Interface:
package nhUtilities.containers2;
public interface Iterator<Element> extends Cloneable, java.util.Iterator<Element>
{
public void reset ();
public void advance ();
public boolean done ();
public Element get ();
public boolean equals (Object obj);
public boolean traverses (Object container);
public Object clone ();
public void setEqualTo (Iterator<Element> other);
public boolean hasNext ();
public Element next ();
public void remove ();
}
In my code, I have a private class called EntryIterator. It extends an AbstractIterator, but implements the Iterator above.
My current implementation is as follows:
private class EntryIterator<Element> extends AbstractIterator<Element>
implements Iterator<Element>
{
protected Iterator<Key> keyIterator;
protected Dictionary<Key,Value> dictionary;
public EntryIterator(Dictionary<Key,Value> dictionary)
{
keyIterator = keys.iterator();
this.dictionary = dictionary;
}
public void reset()
{ keyIterator = keys.iterator(); }
/**
* #Requrie !this.done()
*/
public void advance()
{ keyIterator.advance(); }
public boolean done()
{ return keyIterator.done(); }
// public Entry<Key,Value> get()
// Violates initial Interface: Results in compile error.
// Return type must be "Element"
public Element get()
{
Key key = keyIterator.get();
Value value = dictionary.get(keyIterator.get());
return (Element) new Entry<Key,Value>(key, value);
}
public boolean traverses(Object container)
{
// TODO Iterator traverses
return false;
}
public void setEqualTo(Iterator<Element> other)
{
this.keyIterator = ((EntryIterator<Element>) other).keyIterator;
this.dictionary = ((EntryIterator<Element>) other).dictionary;
}
}
I have done multiple varieties of this class regarding its types, but none of them seem to be compatible with my Dictionary. Should I keep the formatting as is above, I get an error on my Dictionary's iterator() function:
public Iterator<Entry<Key,Value>> iterator()
{
return new EntryIterator<Entry<Key,Value>>(this);
}
The error states it is "The return type is incompatible for Dictionary.iterator()"
Should I change the type of the EntryIterator class' type to:
private class EntryIterator<eEntry<Key,Value>> extends AbstractIterator<Element>
implements Iterator<Element>
I simply get an error saying "Syntax error expected on token '<'" as well as another incompatibility error on my Dictionary.Iterator() function.
Can someone point me in the right direction as to how I can link up all of these different types to get them to return what my contract for Dictionary demands?
I have attempted asking my question during the class, via email to the instructor, as well as one on one merely to be avoided. Any help would be much appreciated.
So, the problem was actually with my class instantiation... Here for everyone with similar issues:
private class EntryIterator extends AbstractIterator<Entry<Key,Value>> implements
nhUtilities.containers2.Iterator<Entry<Key, Value>>
Related
public interface Iterator<T> {
// Returns true if the iterator is valid (points to an element), false otherwise.
boolean isValid();
// Returns the current element and moves forward. This method can only be called if the iterator is valid. If the iterator points to the last element, it becomes invalid after the call.
T next();
// Returns the current element and moves backwards. This method can only be called if the iterator is valid. If the iterator points to the first element, it becomes invalid after the call.
T prev();
}
In a class that does not implement interface Iterator, how is it possible to create a method that returns Iterator<K>, when you can only create methods for an interface inside a class that implements it?
public class ABC<K> implements EFG<K>{
public Iterator<K> minIt() {
//method body
//return Iterator<K> variable
}
}
The class ABC containing the method minIt() does not implement Iterator<T>
(No classes implement the interface Iterator <T> )
You can use an Anonymous Class that implements the interface:
For instance:
interface Foo<T> {
T foo();
}
class Bar<T> {
T t;
public Foo<T> bar() {
return new Foo<T>() { // <-- Anonymous class implementing `Foo`
public T foo() {
return t;
}
};
}
}
Execution:
Bar<String> b = new Bar<>();
b.t = "hello"; // with a setter in real life
Foo<String> f = b.bar();
f.foo(); // will return "hello"
The other option which I think would be the most common is to use a method that returns the interface, for instance the list interface has an iterator() method even though it itself doesn't implements the Iterator interface.
List<String> list = new ArrayList<>();
Iterator<String> stringIterator = list.iterator();
Here's the implementation
Simple. By making a class that implements it. Note that you have a type that you came up with on your own and you named it Iterator. Given that java.util.Iterator exists, this is a really bad idea. You should pick another name.
public class ABC<K> implements EFG<K> {
// Let's say this contains the items that can be iterated over.
private List<K> list = new ArrayList<K>();
class MyIterator implements my.pkg.Iterator<K> {
private int position = 0;
#Override public boolean isValid() {
return position > -1 && position < list.size();
}
#Override public K next() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position++);
}
#Override public K prev() {
if (!isValid()) throw new NoSuchElementException();
return list.get(position--);
}
}
public Iterator<K> minIt() {
return new MyIterator<K>();
}
}
Note that classes that you put in classes can only be constructed in instance contexts within that class: They have a 'secret' field of your outer's type. Hence why the code in MyIterator can access the list field of your outer class.
Java has 'anonymous inner class literal' syntax which lets you shorten this: Instead of explicitly declaring class MyIterator, you can also write:
public Iterator<K> minIt() {
return new your.pkg.Iterator<K>() {
private int position = 0;
#Override public boolean isValid() {
// same code goes here as the previous snippet
}
};
}
This anonymous inner class form is a lot more common. It's just syntax sugar - a shorter way to write the same thing.
I wrote this piece of code, and it works fine. but I have a question:
why it should be public class PeekingIterator<E> implements Iterator<E>, not
public class PeekingIterator implements Iterator<E>. I ask this because if I replace E with Integer in the code, it will work. I mean public class PeekingIterator implements Iterator<Integer> is correct.
import java.util.Iterator;
public class PeekingIterator<E> implements Iterator<E> {
private E nextElem;
private boolean hasNextElem;
private Iterator<E> iter;
public PeekingIterator(Iterator<E> iterator) {
iter = iterator;
nextElem = next();
hasNextElem = true;
}
public E peek() {
return nextElem;
}
#Override
public E next() {
if (!hasNextElem) {
throw new RuntimeException();
}
E res = nextElem;
if (hasNext()) {
nextElem = iter.next();
hasNextElem = true;
} else {
hasNextElem = false;
}
return res;
}
#Override
public boolean hasNext() {
return hasNextElem;
}
}
E is an identifier. If you say that class PeekingIterator<E> implements Iterator<E>, the compiler knows that this identifier is a generic type parameter.
This allows you to instantiate PeekingIterator as:
PeekingIterator<Integer> it1 = new PeekingIterator<>();
or
PeekingIterator<String> it2 = new PeekingIterator<>();
i.e. your PeekingIterator class can iterate over any type of elements.
If you declare PeekingIterator as class PeekingIterator implements Iterator<E>, the compiler searches for some type (class or interface) named E. If it doesn't find it, that's a compilation error.
If you declare class PeekingIterator implements Iterator<Integer>, this works, since Integer is a class. This limits your PeekingIterator to always iterate over Integer elements.
I'm having trouble understanding a method. I have methods that I need to fill out, but I don't really understand the first one. How can Iterable be a return type and how is it used ? An example would be great..
#Override
public Iterable<ClientInterface> getNeighbours() {
return null;
}
#Override
public void addNeighbour(ClientInterface newNeighbour){
//TODO Implement me!
}
#Override
public void removeNeighbour(String clientID) {
//TODO Implement me!
}
It looks like your class should have an implementation of Iterable<ClientInterface> as a class member, like ArrayList.
Let's use this as an example:
public class Bus {
private ArrayList<Person> riders;
... //constructors and other methods
public Iterable<Person> getRiders() {
return riders;
}
... //other methods
}
Everything can be a return type: an enum, a class, an interface, an int, an exception etc.
Iterable is an interface which could be used to use the return in a foreach call (that's why you can use for(T something : AnArrayList) because ArrayList<T> implements Iterable<T>)
Now, my answer contains an example:
We have a method getNeighbours which returns Iterable<ClientInterface>
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>();
}
Well, ok since Iterable is just an interface we need to implement methods or use an implementation.
Since it's something which we should do manually we should implement the methods by ourself.
The only method (in Java8, there are 3 methods but we will ignore it) is iterator() which returns an iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return null;
}
};
}
Iterator is another interface which is used to provide the logic to iterate over the collection, a list of items etc.
We are forced to implements two methods: hasNext and next
hasNext is used to determinate if there are more items to iterate over, next is used to iterate over it.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
#Override
public boolean hasNext()
{
return false;
}
#Override
public ClientInterface next()
{
return null;
}
};
}
};
}
We here need to remember which was our last position so we would create a field inside our Iterator.
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
#Override
public boolean hasNext()
{
return false;
}
#Override
public ClientInterface next()
{
return null;
}
};
}
};
}
Here the problem: What we should iterate? It depends to you, an example could be:
public Iterable<ClientInterface> getNeighbours()
{
return new Iterable<ClientInterface>()
{
#Override
public Iterator<ClientInterface> iterator()
{
return new Iterator<ClientInterface>()
{
private int position;
private ClientInterface[] items = new ClientInterface[]{new ClientInterface(), new ClientInterface()};
#Override
public boolean hasNext()
{
return position != items.length;
}
#Override
public ClientInterface next()
{
if (!hasNext()) throw new NoSuchElementException();
return items[position++];
}
};
}
};
}
Note here how we created an array of items and used our two methods hasNext and next to provide a way to iterate over it.
Every call of next increment the internal pointer, and our hasNext method just checks if the pointer reached the end of the array.
Collections like ArrayList, LinkedList etc. already did the job for you and better (implements remove method) you can get this iterator by using ArrayList.iterator()
Now you could write something like:
for (ClientInterface el : yourClass.getNeighbours())
{
System.out.println(el);
}
Iterable<T> is an interface. What this means is that when you receive it as a return value from a method, you actually receive an implementation of it. So, although you don't know what the name of that implementation is (the name of the class that implements the Iterable<T> interface), you can still access the methods that it implements, and act upon it.
Some built-in implementations include ArrayList, LinkedList, HashSet, PriorityQueue, and Stack.
When you need to return an interface type, you must return an implementation of it.
I'm learning design patterns from 'Head First' series. The book is a bit outdated (no generic types ), so I'm trying to rewrite some of it. I'm supposed to write Wrapper on Iterator to work like Enumerator methods and test it with ArrayList.
The "original" version looked like this(below). I've tried to make it generic class such as <E> or even <T<E>>, but it didn't work. I want to be also sure that it will work for any kind of iterator, not only ArrayList like ArrayList<T>. What is the proper way to implement this ?
public class IteratorWrapper implements Enumeration {
Iterator iterator;
public IteratorWrapper(Iterator iterator){
this.iterator = iterator;
}
public boolean hasMoreElements(){
return iterator.hasNext();
}
//Return generic Type T
public Object nextElement(){
return iterator.next();
}
}
Test class
public class WrapperTest {
public static void main(String[] args){
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("element1");
arrayList.add("element2");
//This part will be rewritten when wrapper will work
IteratorWrapper iteratorWrapper = new IteratorWrapper(arrayList.iterator());
while(iteratorWrapper.hasMoreElements()){
System.out.println(iteratorWrapper.nextElement());
}
}
}
You can add a generic parameter like this:
public class IteratorWrapper<T> implements Enumeration<T> {
Iterator<T> iterator;
public IteratorWrapper(Iterator<T> iterator){
this.iterator = iterator;
}
public boolean hasMoreElements(){
return iterator.hasNext();
}
public T nextElement(){
return iterator.next();
}
}
Then, your initialization will look like this:
IteratorWrapper<String> iteratorWrapper = new IteratorWrapper<String>(arrayList.iterator());
I have the following interface:
public interface DataSet<T> extends Iterable<T> {
public int nExamples();
public T getExample(int index);
public Iterator<T> iterator();
}
Then a class implementing this interface:
public class StringTupleDataset implements DataSet<StringTuple> {
Vector<StringTuple> examples;
public StringTupleDataset(Vector<StringTuple> examples) {
if(examples == null)
throw new IllegalArgumentException("null parameter: examples");
this.examples = examples;
} // constructor
#Override
public int nExamples() {
return examples.size();
} // nExamples
#Override
public StringTuple getExample(int index) {
return examples.get(index);
} // getExample
#Override
public Iterator<StringTuple> iterator() {
return examples.iterator();
} // getAllExamples
} // class
The class StringTupleDataset compiles with no problem.
However, when I try and write this piece of code in another class:
public abstract class AbstractOntologyFiller<T> {
private AbstractOntologyFiller() {}
public static <T> void fill(OntologyManager ontoManager, DataSet<T> dataset) {
for(T e : dataset.iterator()) {
// do something
} // for
} // fill
} // class
I have a compilation error saying:
Can only interate over an array or an instance of java.lang.Iterable
Is there anyone who can help me?
You cannot iterate over an Iterator, but you can iterate through an Iterable.
for(T e : dataset)
will be enough, since Dataset extends Iterable, while dataset.iterator gives you an Iterator.
You just need to iterate over dataset instead of dataset.iterator()
Explanation: the for loop is expecting an Iterable. The Iterable is not the iterator: it is the object that has the iterator() method on it.
Ok, got the error.
I should have written:
public static <T> void fill(OntologyManager ontoManager, DataSet<T> dataset) {
for(T e : dataset) { // (without .iterator()