LinkedList是通过双向链表实现的。
下面实现LinkedList类的以下方法:
- clear():清空整个链表
- size():获取链表的大小
- isEmpty():判断链表是否为空
- get(int index):获取链表在某个索引处的节点中的数据
- set(int index,Object data):设置链表中在index索引处的节点中的数据,并返回该索引之前的节点中的数据
- add(Object data):往链表中添加节点元素(其实新添加的节点都是尾节点,尾插法)
- remove(int index):删除链表中该索引出的节点,并返回该索引之前的节点中的数据
- 实现LinkedList的迭代器(Iterator),实现hasnext()、next()、remove()方法,这里remove()方法必须在调用了next()方法之后才能调用
package com.test.test;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Test3 {
public static void main(String[] args) {
MyLinkedList<String> mList = new MyLinkedList<String>();
mList.add("纯");
mList.add("牛");
mList.add("奶");
System.out.println(mList.isEmpty());
System.out.println(mList.size());
mList.set(1, "酸");
for (int i = 0; i < mList.size(); i++) {
String data = mList.get(i);
System.out.println(data);
}
Iterator iterator = mList.iterator();
while(iterator.hasNext()){
String data = (String) iterator.next();
iterator.remove();
System.out.println(data);
}
System.out.println(mList.size());
mList.clear();
System.out.println(mList.isEmpty());
System.out.println(mList.size());
}
}
/**
* 自定义的LinkedList类 2015年10月20日 下午8:57:58
*
* @author 张耀晖
*
* @param <Object>
*/
class MyLinkedList<Object> implements Iterable<Object> {
private int theSize;// 链表的大小
private Node<Object> beginMarker;// 头节点
private Node<Object> endMarker;// 尾节点
public MyLinkedList() {
clear();
}
// 清空链表
public void clear() {
beginMarker = new Node(null, null, null);// 初始化头节点
endMarker = new Node(null, beginMarker, null);// 初始化尾节点
beginMarker.next = endMarker;// 设置头节点的后继节点为尾节点
theSize = 0;// 链表大小设为0
}
// 获取链表的大小
public int size() {
return theSize;
}
// 判断链表是否为空
public boolean isEmpty() {
return size() == 0;
}
// 获取链表中index位置处的数据
public Object get(int index) {
return getNode(index).data;
}
// 修改链表中index位置处的节点的数据,返回该位置原先的节点的数据
public Object set(int index, Object data) {
Node<Object> indexNode = getNode(index);// 得到该位置的原先的节点
Object indexData = indexNode.data;// 得到该位置原先节点的数据
indexNode.data = data;// 修改该位置出的节点的数据
return indexData;
}
// 向链表中的最后的位置添加数据
public boolean add(Object data) {
add(size(), data);
return true;
}
// 向链表的index位置添加数据data
public void add(int index, Object data) {
Node<Object> indexNode = getNode(index);// 得到该位置的原先的节点
Node<Object> newNode = new Node(data, indexNode.prior, indexNode);// 构造新的节点,并设置该节点的前驱节点为原先节点的前驱节点,后继节点为原先的节点
newNode.prior.next = newNode;// 修改原先节点的后继节点为新节点
indexNode.prior = newNode;// 原先节点的前驱节点为新节点
theSize++;// 链表大小加1
}
// 删除链表index位置处的数据,返回删除位置节点的数据
public Object remove(int index) {
Node<Object> indexNode = getNode(index);// 得到该位置的原先的节点
remove(indexNode);
return indexNode.data;
}
// 删除链表中的该节点
private void remove(Node<Object> indexNode) {
indexNode.prior.next = indexNode.next;// 设置原先节点的前驱节点的后继节点为原先节点的后继节点
indexNode.next.prior = indexNode.prior;// 设置原先节点的后继节点的前驱节点为原先节点的前驱节点
theSize--;// 链表的大小减1
}
// 返回给定位置处的节点元素
private Node<Object> getNode(int index) {
Node<Object> indexNode = null;
if (index < 0 || index > size()) { // 判断输入的index索引是否合法
throw new IndexOutOfBoundsException();
}
if (index < size() / 2) {// 判断index在整个链表的前半部分
indexNode = beginMarker.next;// 假设indexNode为链表的第一个节点
for (int i = 0; i < index; i++) {// 依次根据next找到index索引处的节点
indexNode = indexNode.next;
}
} else {// 判断index在整个链表的后半部分
indexNode = endMarker;// 假设indexNode为链表的尾节点
for (int i = size(); i > index; i--) {// 依次根据prior找到index索引出的节点
indexNode = indexNode.prior;
}
}
return indexNode;
}
@Override
public Iterator<Object> iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<Object> {
private Node<Object> current = beginMarker.next;// 初始化current为链表的第一个节点
private boolean okToRemove = false;// 是否可以使用remove()方法的标志
@Override
// 判断是否存在下一个节点
public boolean hasNext() {
return current != endMarker;// 只要current不是尾节点,说明current之后还存在下一个节点
}
@Override
// 返回下一个节点中的数据
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Object data = current.data;
current = current.next;
okToRemove = true;
return data;
}
@Override
// 删除节点
public void remove() {
if (!okToRemove) {// 作用是使得remove方法只能在next()使用之后调用
throw new IllegalStateException();
}
MyLinkedList.this.remove(current.prior);// 删除当前节点的前驱节点,也就是刚才通过next()返回的节点
okToRemove = false;
}
}
/*
* Node(节点类)
*/
private class Node<Object> {
public Object data;
public Node<Object> prior;
public Node<Object> next;
public Node(Object data, Node<Object> prior, Node<Object> next) {
this.data = data;
this.prior = prior;
this.next = next;
}
}
}
打印结果: