この質問に触発されました: Iterableを実装する方法 次のようなコードを作成するために、基本的なリンク リストの実装を作成し、イテレータを実装することにしました。
MyList<String> myList = new MyList<String>();
myList.add("hello");
myList.add("world");
for(String s : myList) {
System.out.println(s);
}
class MyList<T> implements Iterable<T>
aprivate static class Node<T>
とa を使用して aを作成することで、コードを扱うのは難しくありませんでしたprivate class MyListIterator<T> implements Iterator<T>
が、独自のバージョンの を実装するときに問題が発生しました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;
}
}
}
}
このエラー メッセージは私の好奇心をかき立てました。私はこの問題についてネットで調べていましたが、何も見つかりませんでした (または、おそらく私はこの種の問題を検索するのが得意ではありません)。同じ型の 2 つの変数が比較されているが、互いに割り当て可能ではない理由は何でしょうか?
ところで、LinkedList
Java 設計者がこれをどのように実装したかをコードを見て確認し、それを自分の実装にコピー/貼り付け/適応させることができることはわかっていますが、実際の問題について説明と理解が必要です。
クラスの現在の実装を示す完全なコードMyList
:
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) {
//problem here
head = headItr.getNext();
}
//implementation still under development...
}
}
@Override
public Iterator<T> iterator() {
return new MyListIterator<T>(head);
}
}