要想使用迭代器或者foreach输出链表元素,那么就要实现Iterable接口
然后定义一个内部类实现Iterator接口
一共重写3个方法 这个链表就可以使用迭代器输出了 也就可以使用foreach了
class LinkImpl<T> implements ILink<T>,Iterable<T> {
@Override
public Iterator<T> iterator() {
return new LinkImplIter();
}
private class LinkImplIter implements Iterator{
int cursor = 0; //指针从0开始
@Override
public boolean hasNext() {
return cursor != size(); //此时还有内容
}
@Override
public Object next() {
try {
int i = cursor;
T next = get(i);
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
return next();
}
}
//==========以上实现foreach输出链表内容================
private class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
//第1次调用方法:this=LinkImpl.root;
//第2次调用方法:this=LinkImpl.root.next;
//第3次调用方法:this=LinkImpl.root.next.next;
//...
//增
public void addNode(Node<T> newNode) {
if (this.next == null) { //当前节点之后有空余
this.next = newNode;
} else {
this.next.addNode(newNode);
}
}
//获取全部数据组成的对象数组
public void toArrayNode() {
LinkImpl.this.returnData[LinkImpl.this.foot++] = this.data; //获取当前节点数据
if (this.next != null) {
this.next.toArrayNode(); //递归调用
}
}
//根据索引获取对应元素
public T getNode(int index) {
if (LinkImpl.this.foot++ == index) { //索引相同 返回当前数据
return this.data; //返回当前数据
} else {
if (this.next != null) {
return this.next.getNode(index);
} else { //到最后了
return null;
}
}
}
//根据索引修改元素值
public T setNode(int index, T newData) {
if (LinkImpl.this.foot++ == index) {
T temp = this.data; //返回数据
this.data = newData;
return temp;
} else {
if (this.next != null) {
return this.next.setNode(index, newData);
} else {
return null;
}
}
}
//查找指定元素是否存在
public boolean containsNode(T data) {
if (this.data.equals(data)) { //数据判断相同
return true;
} else {
if (this.next != null) {
return this.next.containsNode(data);
} else {
return false;
}
}
}
//删除指定元素
public void removeNode(Node<T> previous, T data) {
if (this.data.equals(data)) {
previous.next = this.next; //空出当前节点
} else {
if (this.next != null) { //还有后续节点
this.next.removeNode(this, data);
}
}
}
}
//==============以上为内部的节点关系类==================
private Node<T> root; //根节点
private int count; //统计元素个数
private int foot; //索引角标
private Object[] returnData; //返回数组
@Override
public void add(T data) {
if (data == null) { //排除掉所有的空元素
return;
}
Node<T> newNode = new Node<T>(data); // 将数据封装在节点中
if (this.root == null) { // 没有根节点
this.root = newNode;
} else { //此时根节点存在
this.root.addNode(newNode); //交由Node类处理
}
this.count++;
}
@Override
public int size() { //获取链表内存储元素的个数
return this.count;
}
@Override
public boolean isEmpty() {
// return this.count==0; //建议使用下面的方式 调用size()方法
return this.size() == 0;
}
@Override
public Object[] toArray() {
if (this.size() == 0) { //没有元素则返回空
return null;
}
this.foot = 0; //角标清零
this.returnData = new Object[this.size()];
this.root.toArrayNode(); //交给Node类负责处理
return this.returnData; //返回处理结果
}
@Override
public T get(int index) {
if (index >= this.size() || index < 0) {
return null;
}
this.foot = 0; //foot清0
return this.root.getNode(index); //交由Node类处理
}
@Override
public T set(int index, T newData) {
if (index >= this.size() || index < 0) {
return null;
}
this.foot = 0;
return this.root.setNode(index, newData);
}
@Override
public boolean contains(T data) {
if (this.size() == 0 || data == null) {
return false;
} else {
return this.root.containsNode(data);
}
}
@Override
public void remove(T data) {
if (this.size() == 0 || data == null) {
return;
}
if (this.root.data.equals(data)) { //根节点
this.root = this.root.next; //修改根节点
} else { //后续判断可以从第二个节点开始
if (this.root.next != null) {
this.root.next.removeNode(this.root, data);
}
}
count--;
}
@Override
public void clear() {
this.root = null; //清空所有引用
this.count = 0;
}
}
来源:CSDN
作者:M&Y
链接:https://blog.csdn.net/qq_37883866/article/details/103709762