
org.nutz.lang.util.SimpleNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nutz Show documentation
Show all versions of nutz Show documentation
Nutz, which is a collections of lightweight frameworks, each of them can be used independently
package org.nutz.lang.util;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.nutz.lang.Each;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
public class SimpleNode implements Node {
public SimpleNode() {}
private T obj;
private SimpleNode parent;
private SimpleNode prev;
private SimpleNode next;
private SimpleNode firstChild;
private SimpleNode lastChild;
public T get() {
return obj;
}
public Node set(T obj) {
this.obj = obj;
return this;
}
public Node parent() {
return parent;
}
public Node top() {
if (null == parent)
return this;
return parent.top();
}
public Node prev() {
return prev;
}
public Node prev(Node node) {
SimpleNode nd = (SimpleNode) node;
this.prev = nd;
nd.next = this;
nd.parent = parent;
return this;
}
public Node next() {
return next;
}
public Node next(Node node) {
SimpleNode nd = (SimpleNode) node;
this.next = nd;
nd.prev = this;
nd.parent = this;
return this;
}
public boolean isRoot() {
return null == parent;
}
public boolean isLast() {
return null == next;
}
public boolean isFirst() {
return null == prev;
}
public List> parents() {
LinkedList> list = new LinkedList>();
Node me = parent;
while (me != null) {
list.addFirst(me);
me = me.parent();
}
return list;
}
public List> getAncestors() {
List> list = new LinkedList>();
Node me = parent;
while (me != null) {
list.add(me);
me = me.parent();
}
return list;
}
public int depth() {
int re = 0;
Node nd = this;
while (null != nd.parent()) {
re++;
nd = nd.parent();
}
return re;
}
public List> getNextSibling() {
List> list = new LinkedList>();
Node me = next;
while (me != null) {
list.add(me);
me = me.next();
}
return list;
}
public List> getPrevSibling() {
List> list = new LinkedList>();
Node me = prev;
while (me != null) {
list.add(me);
me = me.prev();
}
return list;
}
public int index() {
return getPrevSibling().size();
}
public List> getChildren() {
List> list = new LinkedList>();
if (null != firstChild) {
list.add(firstChild);
list.addAll(firstChild.getNextSibling());
}
return list;
}
public int countChildren() {
int re = 0;
if (null != firstChild) {
Node me = firstChild;
while (me != null) {
re++;
me = me.next();
}
}
return re;
}
public boolean hasChild() {
return null != firstChild;
}
public Node firstChild() {
return firstChild;
}
public Node lastChild() {
return lastChild;
}
public Node parent(Node node) {
parent = (SimpleNode) node;
node.add(this);
return this;
}
public Node clearChildren() {
firstChild = null;
lastChild = null;
return this;
}
@SuppressWarnings("unchecked")
public Node add(Node>... nodes) {
if (nodes.length == 0) {
return this;
}
if (nodes.length == 1) {
SimpleNode node = (SimpleNode) nodes[0];
node.parent = this;
if (!this.hasChild()) {
firstChild = node;
lastChild = node;
node.next = null;
node.prev = null;
} else {
lastChild.next = node;
node.prev = lastChild;
node.next = null;
lastChild = node;
}
} else {
SimpleNode theNode = (SimpleNode) nodes[0];
theNode.parent = this;
theNode.next = (SimpleNode) nodes[1];
// 加入子节点链表
if (null == lastChild) {
firstChild = theNode;
} else {
lastChild.next = theNode;
}
// 循环添加
int i = 1;
for (; i < nodes.length - 1; i++) {
SimpleNode node = (SimpleNode) nodes[i];
node.parent = this;
node.prev = (SimpleNode) nodes[i - 1];
node.next = (SimpleNode) nodes[i + 1];
}
lastChild = (SimpleNode) nodes[i];
lastChild.parent = this;
lastChild.prev = (SimpleNode) nodes[i - 1];
}
return this;
}
public Node addFirst(Node node) {
((SimpleNode) node).parent = this;
if (!this.hasChild()) {
firstChild = (SimpleNode) node;
lastChild = (SimpleNode) node;
((SimpleNode) node).next = null;
((SimpleNode) node).prev = null;
} else {
firstChild.prev = (SimpleNode) node;
((SimpleNode) node).next = firstChild;
((SimpleNode) node).prev = null;
firstChild = (SimpleNode) node;
}
return this;
}
public Node child(int index) {
if (hasChild())
return firstChild.next(index);
return null;
}
@SuppressWarnings("unchecked")
public > void eachChild(Each callback) {
SimpleNode nd = firstChild;
int i = 0;
while (nd != null) {
callback.invoke(i++, (E) nd, -1);
nd = nd.next;
if (nd == firstChild)
throw Lang.makeThrow("If i am here, tell me -_-!");
}
}
public Node desc(int... indexes) {
Node me = this;
for (int i : indexes) {
if (!me.hasChild())
return null;
me = me.firstChild().next(i);
}
return me;
}
public Node next(int index) {
if (index < 0)
return null;
Node me = this;
while (index > 0 && me != null) {
index--;
me = me.next();
}
if (index > 0)
return null;
return me;
}
public Node prev(int index) {
Node me = this;
while (index > 0 && me != null) {
index--;
me = me.prev();
}
return me;
}
public Node insertBefore(int index, Node node) {
SimpleNode me = (SimpleNode) child(index);
if (null != me) {
((SimpleNode) node).next = me;
((SimpleNode) node).prev = me.prev;
me.prev.next = (SimpleNode) node;
me.prev = (SimpleNode) node;
((SimpleNode) node).parent = this;
if (firstChild == me)
firstChild = (SimpleNode) node;
}
return this;
}
public Node pop() {
if (!hasChild())
return null;
SimpleNode re = lastChild;
lastChild = lastChild.prev;
if (null == lastChild)
firstChild = null;
else
lastChild.next = null;
re.prev = null;
re.next = null;
return re;
}
public Node popFirst() {
if (!hasChild())
return null;
SimpleNode re = firstChild;
firstChild = firstChild.next;
if (null == firstChild)
lastChild = null;
else
firstChild.prev = null;
re.prev = null;
re.next = null;
return re;
}
public Node removeChild(int index) {
if (hasChild()) {
SimpleNode node = (SimpleNode) child(index);
if (null == node)
return null;
else if (node.isLast())
return pop();
else if (node.isFirst())
return popFirst();
node.next.prev = node.prev;
node.prev.next = node.next;
node.prev = null;
node.next = null;
return node;
}
return null;
}
public boolean remove() {
int i = getIndex();
if (i < 0)
return false;
parent.removeChild(i);
return true;
}
public int getIndex() {
if (parent == null)
return -1;
int i = 0;
Node n = parent.firstChild();
while (n != parent.child(i)) {
i++;
}
return i;
}
public String toString() {
StringBuilder sb = new StringBuilder();
appendTo(this, sb, 0);
return sb.toString();
}
static void appendTo(Node> node, StringBuilder sb, int depth) {
sb.append(Strings.dup(" ", depth))
.append(node.get() == null ? "NULL" : node.get().toString());
Node> chd = node.firstChild();
while (chd != null) {
sb.append('\n');
appendTo(chd, sb, depth + 1);
chd = chd.next();
}
}
static class InnerIterator implements Iterator> {
private Node root;
private Node node;
InnerIterator(Node node) {
this.root = node;
if (root.hasChild())
this.node = root.child(0);
else
this.node = root;
}
public boolean hasNext() {
return node != root;
}
public Node next() {
if (node == root)
return null;
Node re = node;
if (node.hasChild()) {
node = node.firstChild();
} else if (!node.isLast()) {
node = node.next();
} else {
while (node.isLast() && !node.isRoot()) {
node = node.parent();
}
if (!node.isRoot())
node = node.next();
}
return re;
}
public void remove() {
throw Lang.makeThrow("No implement yet!");
}
}
public Iterator> iterator() {
return new InnerIterator(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy