版权声明:转载请注明出处 https://blog.csdn.net/weixin_39554102/article/details/85274735
简介:
Links 接口模拟数据结构链表的操作, 继承了 Iterable 接口, 即可以foreach 循环;
Links 具体的操作 有 add、set、remove、get、size;是最为简单的实现
DoubleLinked 的实现参考自:jdk 1.8 LinkedList 实现;
如果对链表的更具体实现请看这:
LinkedList实现浅析
断开一个节点
接口: Links< E >
/**
* <p> 链表的数据结构.包括 add、get、set、remove、size、iterator 方法,是一个极为简单的链表实现。
* <p> 大部分逻辑参考了, jdk 1.8 LinkedList 的源码.
*
* @author chenyq
* @email [email protected]
* @version 2018-12-26
* @param <E>
*/
public interface Links<E> extends Iterable<E> {
/**
* 添加元素
* @param e
* @return
*/
boolean add(E e);
/**
* 获取指定索引的元素
* @param index
* @return
*/
E get(int index);
/**
* 移除指定索引的元素
* @param index
* @return
*/
E remove(int index);
/**
* 修改指定索引的元素
* @param index
* @param e
* @return
*/
E set(int index, E e);
/**
* 获取元素总数量
* @return
*/
int size();
}
实现类: DoubleLinked
public class DoubleLinked<E> implements Links<E>, Serializable, Cloneable {
/**
* 元素数量
*/
private int size;
/**
* 记录第一个节点的指针.
*/
private Node<E> first;
/**
* 记录了最后一个节点的指针
*/
private Node<E> last;
/**
* 统计这个数据结构发生变化的次数, add / remove 操作会导致结构上的改变
*/
protected int modCount;
/**
* 记录数据的节点
*
* @param <E>
*/
private static class Node<E> {
private Node<E> prev;
private E item;
private Node<E> next;
public Node(Node<E> prev, E item, Node<E> next) {
super();
this.prev = prev;
this.item = item;
this.next = next;
}
}
/**
* 迭代器实现,
*
*/
private class LinkItr implements Iterator<E> {
/**
* 最后返回的节点指针, 初始为null
*/
private Node<E> lastReturn;
/**
* 光标, 下一个节点索引
*/
private int cursor;
/**
* 下一个返回的节点指针, 初始为 first 节点
*/
private Node<E> node;
/**
* 判断是否被并发修改过的计数器
*/
private int expectedModCount = modCount;
public LinkItr() {
this.node = first;
}
@Override
public boolean hasNext() {
return cursor < size;
}
@Override
public E next() {
checkConcurrentModification();
if(! hasNext())
throw new NoSuchElementException();
if (node == null) {
throw new NoSuchElementException();
}
// E e = node.item;
lastReturn = node;
node = node.next;
cursor++;
return lastReturn.item;
}
@Override
public void remove() {
if (lastReturn == null) {
throw new NoSuchElementException();
}
unlink(lastReturn);
this.expectedModCount = modCount;
lastReturn = null;
cursor--;
}
void checkConcurrentModification() {
if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
}
}
@Override
public boolean add(E e) {
Node<E> l = last;
Node<E> newNode = new Node<E>(l, e, null);
if (l == null) {
first = last = newNode;
} else {
l.next = last = newNode;
}
size++;
modCount++;
return true;
}
@Override
public E get(int index) {
checkIndex(index);
return node(index).item;
}
/**
* 检查索引是否越界
* @param index
*/
private void checkIndex(int index) {
if (index >= size || index < 0)
throw new IndexOutOfBoundsException("index out : " + index);
}
Node<E> node(int index) {
Node<E> f = first;
for(int i = 0; i < index; i++) {
f = f.next;
}
return f;
}
@Override
public E remove(int index) {
checkIndex(index);
return unlink(node(index));
}
/**
* 从链表中断开指定的节点;
* @param node
* @return
*/
E unlink(Node<E> node) {
// if (node == null) {
// return null;
// }
E e = node.item;
Node<E> prev = node.prev;
Node<E> next = node.next;
// 交换头节指针
if (prev == null) {
first = next;
} else {
prev.next = next;
node.prev = null;
}
// 交换尾节点指针
if (next == null) {
last = prev;
} else {
next.prev = prev;
node.next = null;
}
node.item = null;
size--;
modCount++;
return e;
}
@Override
public E set(int index, E e) {
Node<E> n = node(index);
E oldValue = n.item;
n.item = e;
return oldValue;
}
@Override
public Iterator<E> iterator() {
return new LinkItr();
}
@Override
public int size() {
return size;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
Iterator<E> it = iterator();
while(!it.hasNext()) {
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append('[');
while(true) {
sb.append(it.next());
if (! it.hasNext())
return sb.append(']').toString();
sb.append(",").append(' ');
}
}
}
测试:
public class LinksTest {
private Links<String> links;
@Before
public void init() {
this.links = new DoubleLinked<>();
for(int i = 0; i < 10; i++)
links.add("node- " + i);
}
@Test
public void get() {
System.out.println(links);
System.out.println(links.get(0));
System.out.println(links.get(2));
System.out.println(links.get(links.size() - 1));
System.out.println(links.get(links.size()));
}
@Test
public void remove() {
System.out.println(links);
System.out.println(links.remove(0));
System.out.println(links.remove(2));
System.out.println(links.remove(links.size() - 1));
System.out.println(links);
}
@Test
public void set() {
System.out.println(links);
System.out.println(links.set(0, "node - *"));
System.out.println(links.set(3, "node - *"));
System.out.println(links.set(links.size() - 1, "node - *"));
System.out.println(links);
}
@Test
public void iterator_1() {
Iterator<String> it = links.iterator();
while(it.hasNext())
System.out.println(it.next());
System.out.println(links);
}
@Test
public void iterator_2() {
Iterator<String> it = links.iterator();
while(it.hasNext()) {
System.out.println(it.next());
it.remove();
}
System.out.println(links);
}
@Test
public void iterator_3() {
Iterator<String> it = links.iterator();
while(true) {
System.out.println(it.next());
}
}
@Test
public void iterator_4() {
Iterator<String> it = links.iterator();
while(true) {
it.remove();
}
}
}
源码下载:
如有谬误,欢迎指正…