Inspired by this question: How to implement Iterable I decided to make a basic implementation of a linked list and implement an iterator to have code like this:
MyList<String> myList = new MyList<String>(); myList.add("hello"); myList.add("world"); for(String s : myList) { System.out.println(s); }
It was not easy to compromise the code by creating the class MyList<T> implements Iterable<T> with private static class Node<T> and private class MyListIterator<T> implements Iterator<T> , but then I ran into a problem when implementing my own version of Iterator#remove :
class MyList<T> implements Iterable<T> { private static class Node<T> { //basic node implementation... } private Node<T> head; private Node<T> tail; //constructor, add methods... private class MyListIterator<T> implements Iterator<T> { private Node<T> headItr; private Node<T> prevItr; public MyListIterator(Node<T> headItr) { this.headItr = headItr; } @Override public void remove() { //line below compiles if (head == headItr) { //line below compiles head = head.getNext(); //line below doesn't and gives me the message //"Type mismatch: cannot convert from another.main.MyList.Node<T> to //another.main.MyList.Node<T>" head = headItr.getNext(); //line below doesn't compile, just for testing purposes (it will be deleted) head = headItr; } } } }
This error message aroused my curiosity. I looked on the net about this problem, but found nothing (or, probably, I am not so good at understanding such problems). What will be the reason for comparing two variables of the same type, but not assigned to each other?
By the way, I know that I can just look at the LinkedList code and check how the Java developers implemented this and copied / pasted / adapted it to my own implementation, but I prefer to have an explanation and understanding of the real problem.
Full code that shows my current implementation of the MyList class:
class MyList<T> implements Iterable<T> { private static class Node<T> { private T data; private Node<T> next; public Node(T data) { super(); this.data = data; } public T getData() { return data; } public Node<T> getNext() { return next; } public void setNext(Node<T> next) { this.next = next; } } private Node<T> head; private Node<T> tail; private int size; public MyList() { head = null; tail = null; } public void add(T data) { Node<T> node = new Node<T>(data); if (head == null) { head = node; tail = head; } else { tail.setNext(node); tail = node; } size++; } private class MyListIterator<T> implements Iterator<T> { private Node<T> headItr; private Node<T> prevItr; public MyListIterator(Node<T> headItr) { this.headItr = headItr; } @Override public boolean hasNext() { return (headItr.getNext() != null); } @Override public T next() { T data = headItr.getData(); prevItr = headItr; if (hasNext()) { headItr = headItr.getNext(); } return data; } @Override public void remove() { if (head == headItr) {
java generics static inner-classes
Luiggi Mendoza
source share