本来这次博文要介绍Handler、Message、Looper之间的关系的,但是,我觉得,在讲这个之前我觉得有必要讲一下列表,因为什么呢?我这是为了,下面讲Handler、Message、Looper之间的关系时,需要用到,因为Handler里有个消息队列用到了链表。 好了,咱么开门见山,下面我们就开始来看看双向列表如何实现:
这个代码也是比较简单的,首先不要怪我直接贴代码,因为这个用文字来描述感觉很晦涩,所以我会以代码跟图的结合方式来说:
首先我们来说说双向列表的添加方法:
/**
* 添加节点数据
* @param data
*/
public void add(Object data){
//将数据封装到节点里面去
Node node = new Node(data);
if(head == null){//①
//如果head为空,那么node是不是就是头节点,head、rear都指向它
head = node;
rear = node;
}else{//否则,那么就代表不为空,要么往前加,要么往后加
rear.next = node;
node.prev = rear;
rear = node;
}
}
下面用一副图来帮助理解:
那么接下来,我就来看看删除的方法:
/**
* 查找节点
* @param data
*/
private Node find(Object data){
Node node = head;
while(node != null){
if(node.data.equals(data) && node.data.hashCode() == data.hashCode()){//找到了
break;
}else{//没找到,指向下一个
node = node.next;
}
}
return node;
}
/**
* 删除节点
* @param data
*/
public void remove(Object data){
Node node = find(data);
if(node != null){
if(node == head && node == rear){//找到,删除
head = null;
rear = null;
}else if(node == head){//头节点
head = head.next;
head.prev = null;
}else if(node == rear){//尾节点
rear = rear.prev;
rear.next = null;
}else{//中间节点
head.prev.next = node.next;
head.next.prev = node.prev;
}
}
}
同样是一段code,我相信大家应该看的懂,加上了注释应该好理解,下面同样用一幅图来表示:
我相信有了图,应该很好理解,对吧。对大家来说理解起来应该更加清晰。当然,如果你需要实现迭代的功能,你也可以实现Iteratorable接口,这里我也为大家实现了这一个功能,不过这里我会贴出全部代码:因为这样看起来更加全面。
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
public class MyDoubleLink implements Iterable<Object>{
private class Node{
public Node(Object data){
this.data = data;
}
Node next;
Node prev;
Object data;
}
private Node head;//头节点
private Node rear;//尾节点
/**
* 添加节点数据
* @param data
*/
public void add(Object data){
//将数据封装到节点里面去
Node node = new Node(data);
if(head == null){//①
//如果head为空,那么node是不是就是头节点,head、rear都指向它
head = node;
rear = node;
}else{//否则,那么就代表不为空,要么往前加,要么往后加
rear.next = node;
node.prev = rear;
rear = node;
}
}
/**
* 查找节点
* @param data
*/
private Node find(Object data){
Node node = head;
while(node != null){
if(node.data.equals(data) && node.data.hashCode() == data.hashCode()){//找到了
break;
}else{//没找到,指向下一个
node = node.next;
}
}
return node;
}
/**
* 删除节点
* @param data
*/
public void remove(Object data){
Node node = find(data);
if(node != null){
if(node == head && node == rear){//找到,删除
head = null;
rear = null;
}else if(node == head){//头节点
head = head.next;
head.prev = null;
}else if(node == rear){//尾节点
rear = rear.prev;
rear.next = null;
}else{//中间节点
head.prev.next = node.next;
head.next.prev = node.prev;
}
}
}
@Override
public void forEach(Consumer<? super Object> arg0) {
// TODO Auto-generated method stub
}
@Override
public Iterator<Object> iterator() {//实现增强for循环
Iterator<Object> ite = new Iterator<Object>() {
private Node temp = head;
@Override
public void forEachRemaining(Consumer<? super Object> arg0) {
}
@Override
public boolean hasNext() {
return temp != null;
}
@Override
public Object next() {
Object data = temp.data;
temp = temp.next;
return data;
}
@Override
public void remove() {
}
};
return null;
}
@Override
public Spliterator<Object> spliterator() {
return null;
}
}
好了,就到这里了,我觉得这个对理解MessageQueue非常有好处。如果童鞋们不想黏贴之类的麻烦,我也会把代码打包上传到优快云资源库,到时候大家下载即可。欢迎大家拍砖啊,我需要你们吐槽啊。看完这篇,大家就可以看看 阅读源码,让你彻底理解Handler、Message、Looper之间的关系,相信这篇对你理解他们之间的关系,是很有帮助的。
源码在这:点击打开链接