自己写简单的LinkedList

本文介绍了一个简单的LinkedList实现,包括添加、删除、查找等基本操作。通过源代码展示如何管理双向链表节点,进行索引检查及节点重定向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近复习基础知识,看了下LinkedList源码,决定自己也写写,当然方法不多,只是个简化版。

package 集合;

public class MyLinkList  {
	private transient int size = 0;
	private transient Node  first;
	private transient Node  last;

	public MyLinkList() {
	}

	/**
	 * 返回List的大小
	 * @return size List的大小
	 */
	public int size() {
		return size;
	}

	/**
	 * 添加元素
	 * @param obj 元素
	 */
	public void add(Object obj){
		Node node=new Node();
		node.obj=obj;
		if(first==null){
			node.previous=null;
			node.next=null;
			first=node;
			last=node;
		}else{
			node.previous=last;
			node.next=null;
			last.next=node;
			last=node;
		}
		size++;
	}
	
	/**
	 * 根据索引获取该元素
	 * @param index 索引
	 * @return Object
	 */
	public Object get(int index){
		checkRange(index);
		if(index<(size>>1)){
			Node temp=first;
			for(int i=0;i<index;i++) temp=temp.next;
			return temp.obj;
		}else{
			Node temp=last;
			for(int i=size-1;i>index;i--) temp=temp.previous;
			return temp.obj;
		}
	}
		
	/**
	 * 根据内容删除元素
	 * @param obj 元素内容
	 * @return boolean
	 */
	public boolean remove(Object obj){
		if(obj==null){
			for(Node node=first;node!=null;node=node.next){
				if(node.obj==null){
					RedirectPoint(node);
					return true;
				}					
			}
			return false;
		}else{
			for(Node node=first;node!=null;node=node.next){
				if(obj.equals(node.obj)){
					RedirectPoint(node);
					return true;
				}
			}
			return false;
		}
	}
	
	/**
	 * 根据索引删除元素
	 * @param index 元素的索引
	 * @return boolean 
	 */
	public Object remove(int index){
		checkRange(index);
		if(index<(size>>1)){
			Node node=first;
			for(int i=0;i<index;i++){
				node=node.next;
			}
			Object obj=node.obj;
			RedirectPoint(node);
			return obj;	
		}else{
			Node node=last;
			for(int i=size-1;i>index;i--){
				node=node.previous;
			}
			Object obj=node.obj;
			RedirectPoint(node);
			return obj;			
		}
	}
	
	/**
	 * 查找元素的索引,只返回元素第一次出现的索引,若没有该元素则返回-1;
	 * @param Object 要查找的元素
	 */
	public int find(Object obj){
		int index=0;
		if(obj==null){
			for(Node node=first;node!=null;node=node.next){
				if(node.obj==null) 
				return index;
				index++;
			}
		}else{
			for(Node node=first;node!=null;node=node.next){
				if(obj.equals(node.obj))
				return index;
				index++;
			}
		}
		return -1;
	}
	
	
	//检查索引是否越界
	private void checkRange(int index){
		if(index>=size||index<0){
			try{
				throw new Exception();
			}catch(Exception e){
				System.out.println("数组越界,请检查索引是否超出列表的大小");
				e.printStackTrace();
			}
		}
	}
	
	//删除的内部操作,指针重定向
	private void RedirectPoint(Node node){
		Node up=node.previous;
		Node down=node.next;
		up.next=down;
		down.previous=up;
		size--;
	}
	
	//MylinkList的内部类
	private class Node{
		Object obj;
		Node  previous;
		Node  next;
		Node(){}
	}
}


<think>嗯,用户想了解如何自行实现一个消息队列(MQ)。首先,我需要确定用户的需求层次。他们可能是一个开发者,想深入理解MQ的内部机制,或者是为了特定项目需要自定义解决方案。不管怎样,我需要从基础开始,逐步引导他们。 首先,用户提供的引用中提到了RabbitMQ、Spring Boot集成、Socket链接等,但用户现在想自己实现,所以得抛开现有的中间件,从零开始设计。需要明确消息队列的核心功能:消息存储、生产消费机制、传输协议、持久化等。 第一步,确定基本结构。消息队列的核心是存储消息,可以用内存中的队列结构,比如Python的deque或者JavaLinkedList。但内存队列的问题是一旦宕机数据丢失,所以需要考虑持久化,比如用文件或数据库存储。但用户可能刚开始不需要这么复杂,可以先实现内存版的,后续再扩展。 然后,通信协议。引用里提到了使用Socket链接端口9999,所以可能需要基于TCP或UDP。TCP更可靠,适合消息队列的传输。因此,需要实现一个服务器监听端口,客户端通过Socket连接来生产和消费消息。这里需要处理多线程或异步IO,以支持多个客户端同时连接。 接下来,生产者和消费者的逻辑。生产者发送消息到队列,消费者从队列获取消息。需要考虑消息的格式,比如JSON或二进制协议。另外,消息确认机制(ack)和重试机制,比如消费者处理失败后如何重新入队,这涉及到消息状态的管理,如pending状态。 然后是高级功能,比如持久化。可以将消息入文件,启动时从文件加载。但文件操作可能会影响性能,需要权衡。路由机制的话,比如主题订阅或者直连路由,可能需要引入交换机和绑定,但基础版本可能只需要一个简单的队列。 代码示例方面,用户提供的引用中有Python的例子,可能用户对Python比较熟悉。不过考虑到消息队列通常用Java或Erlang,但教程可能需要简化,用Python更易懂。比如用Python的socketserver模块创建TCP服务器,使用多线程处理连接,用队列存储消息。 测试部分,可以用telnet或简单的客户端代码来发送和接收消息。但用户可能需要更详细的步骤,比如如何运行服务器,如何发送消息等。 还要考虑问题,比如消息顺序、重复、丢失如何处理。这些在自定义MQ中都是挑战,可能需要引入消息ID、重试次数、确认机制等。引用3中提到acknowledge和pending的API,所以在实现时需要处理消息的确认,未确认的消息重新放回队列。 最后,对比现有中间件,说明自定义的局限性,比如性能、可靠性不如RabbitMQ或Kafka,但适合学习或特定场景。这样用户能理解何时该自研,何时用现成方案。 总结下来,步骤应该是:定义数据结构,实现通信层,处理生产消费逻辑,添加持久化,高级功能,最后测试和优化。同时,提供代码示例和可能的问题,帮助用户逐步实现。</think>### 如何自行实现消息队列(MQ) #### 1. 核心功能设计 消息队列的核心功能包括**消息存储**、**生产者-消费者通信机制**、**消息传输协议**和**持久化**。以下是分步实现思路: **1.1 数据结构定义** - 使用内存队列存储消息(如`deque`或链表),支持先进先出(FIFO)特性。 - 定义消息格式为`JSON`或二进制协议,例如: ```json { "id": "消息唯一标识", "content": "消息内容", "status": "pending/acked" } ``` **1.2 通信协议实现** - 基于`TCP`协议实现客户端与服务器的通信(如引用[2]中的Socket链接)。 - 服务器监听端口(如`9999`),客户端通过`send`和`recv`方法生产/消费消息。 **1.3 生产者-消费者逻辑** - **生产者**:将消息推送到队列尾部。 - **消费者**:从队列头部拉取消息,处理完成后发送`ACK`确认(如引用[3]的`acknowledge`机制)。 --- #### 2. 基础实现代码示例(Python) 以下是一个基于Socket的简化版MQ实现: ```python # MQ服务器端(mq_server.py) import socket import json from collections import deque class SimpleMQ: def __init__(self): self.queue = deque() self.pending = {} # 存储未确认的消息 def produce(self, message): self.queue.append(message) def consume(self): if self.queue: msg = self.queue.popleft() msg_id = id(msg) self.pending[msg_id] = msg # 标记为待确认 return json.dumps({"id": msg_id, "content": msg}) return None def acknowledge(self, msg_id): if msg_id in self.pending: del self.pending[msg_id] server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 9999)) server.listen(5) mq = SimpleMQ() while True: conn, addr = server.accept() data = conn.recv(1024).decode() if data.startswith("PRODUCE:"): message = data.split(":", 1)[1] mq.produce(message) conn.send(b"ACK") elif data == "CONSUME": msg = mq.consume() conn.send(msg.encode() if msg else b"NO_MESSAGE") elif data.startswith("ACK:"): msg_id = int(data.split(":")[1]) mq.acknowledge(msg_id) conn.send(b"ACK_OK") conn.close() ``` --- #### 3. 关键问题与优化 | **问题** | **解决方案** | |-------------------|-----------------------------------------| | 消息丢失 | 引入持久化(如入文件或数据库) | | 重复消费 | 为消息添加唯一ID,消费后标记状态 | | 高并发处理 | 使用多线程/异步IO模型(如`asyncio`) | | 流量削峰 | 限制队列最大长度,拒绝超限请求(引用[1]) | --- #### 4. 高级功能扩展 - **持久化存储**:将消息入文件或Redis,重启时恢复队列。 - **路由机制**:实现类似RabbitMQ的`Exchange`和`Binding`(引用[4])。 - **延迟队列**:通过定时任务检查到期消息。 - **广播模式**:维护多个消费者列表,推送消息到所有订阅者。 --- #### 5. 测试与验证 1. **启动服务器**: ```bash python mq_server.py ``` 2. **生产者发送消息**: ```bash echo "PRODUCE:Hello World" | nc localhost 9999 ``` 3. **消费者拉取消息**: ```bash echo "CONSUME" | nc localhost 9999 ``` --- #### 6. 对比现有中间件 | **特性** | 自定义MQ | RabbitMQ/Kafka | |----------------|---------------------|----------------------| | 可靠性 | 依赖实现(如文件持久化) | 高(集群、副本) | | 性能 | 较低(单机) | 高(分布式架构) | | 适用场景 | 学习/简单场景 | 生产级系统(引用[4]) | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值