java实现链表(模拟LinkedList)

本文通过创建静态内部类Node模拟链表结构,并实现LinkedList的主要方法,包括add、get、remove等。同时,为了支持foreach遍历,实现了Iterable接口。代码示例展示了如何使用这些方法并给出了测试效果。

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

      众所周知,链表是由一个个节点连接在一起,这里我们就先创建一个节点类,为了达到模拟效果,我们选择建一个Node的静态内部类。

我们要想模拟LinkedList,就得先了解LinkedList的类包含的方法:

 add(Object)   dd(int,Object)   addFirst   addLast   get(int index)   remove    getIndex  removeFirst  removeLast等

以及LinkedList 所实现的接口


    我们为了要使用foreach语句遍历,就必须实现Iterable接口。附上代码:

import java.util.Iterator;
public class MyLinkedList<T> implements Iterable<T>{
	private Node<T> first;//指向第一个节点的工作指针
	private Node<T> current;//指向最后一个节点的工作指针
	private int size=0;//统计链表长度
	private static class Node<T>{
		T data;
		Node<T> next;
	}
	//获取长度
	public int size(){
		return size;
	}
	//添加节点
	public void add(T data){
		Node<T> newNode=new Node<T>();
		newNode.data=data;
		
		if(first==null){
			first=newNode;
			current=newNode;
			size++;
			return;
		}
		current.next=newNode;
		current=newNode;
		size++;
	}
	//插入第一个位置
	public void addFirst(T data){
		Node<T> newNode=new Node<T>();
		newNode.data=data;
		
		if(first==null){
			first=newNode;
			current=newNode;
			size++;
			return;
		}
		newNode.next=first;
		first=newNode;
		size++;
	}
	public void addLast(T data){
		add(data);
	}
	//根据索引添加节点
	public void add(int index,T data){
		Node<T> newNode=new Node<T>();
		newNode.data=data;		
		
		Node node=getNode(index);//指向指定索引之前的节点		
		
		if(node==null){
			addFirst(data);
			return;
		}
		newNode.next=node.next;
		node.next=newNode;
		size++;
	}
	/**
	 * 得到指定索引的数据
	 * @param index
	 * @return 数据
	 */
	public T get(int index){
		return getNode(index).next.data;
	}
	/**
	 * 得到指定索引的前一个节点
	 * @param index
	 * @return
	 */
	private Node<T> getNode(int index) {
		Node<T> node=null;
		if(index==0){
			//插入到第一个
			return null;
		}
		if(index<size){
			//插入中间
			node=first;
			for(int i=1;i<index;i++){
				node=node.next;
			}
			return node;
		}
		return current;
	}
	/**
	 * 迭代器
	 */
	public Iterator<T> iterator(){
		return new Iterator<T>() {
			Node<T> cur;
			@Override
			public boolean hasNext() {
				if(cur==null && first!=null){
					cur=first;
					return true;
				}
				if(cur.next!=null){
					cur=cur.next;
					return true;
				}
				return false;
			}
			@Override
			public T next() {
				return cur.data;
			}
		};
	}
	/**
	 * 移除数据
	 * @param data
	 */
	public void remove(T data){
		//查找数据的索引
		int index=getIndex(data);
		remove(index);
	}
	/**
	 * 通过数据查找第一次出现的索引
	 * @param data
	 * @return
	 */
	private int getIndex(T data) {
		Node node=first;
		for(int i=0;i<size;i++){
			if(node.data.equals(data)){
				return i;
			}
			node=node.next;
		}
		return -1;
	}
	/**
	 * 移除指定索引的数据
	 * @param index
	 */
	public void remove(int index){
		Node prev=getNode(index);
		Node node=getNode(index+1);
		prev.next=node.next;
		size--;
	}
	/**
	 * 移除第一个
	 */
	public void removeFirst(){
		first=first.next;
		size--;
	}
	/**
	 * 移除最后一个
	 */
	public void removeLast(){
		//查找倒数第二个节点
		Node node=getNode(size-1);
		node.next=null;
		current=node;
		size--;
	}
	/**
	 * 修改指定索引的数据
	 * @param index
	 * @param newData
	 */
	public void set(int index,T newData){
		//得到指定索引节点
		Node node=getNode(index+1);
		if(node==null){
			node=first;
		}
		//修改节点上的数据
		node.data=newData;
	}
}


到这里我们基本模拟了LinkedList类的所有方法,我们赶紧来测试下:

public class Demo {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MyLinkedList<String> list=new MyLinkedList<String>();
		list.add("AAA");
		list.add("BBB");
		list.add("CCC");
		list.addFirst("DDD");
		list.addLast("EEE");
		list.add(2,"FFF");
		
		for(String s:list){
			System.out.println(s);
		}
		String s=list.get(2);
		System.out.println("下标为2的元素:"+s);
		
		list.set(2, "TEST");
		System.out.println("Size:"+list.size());
		list.removeFirst();
		list.removeLast();
		list.remove(2);
		System.out.println("------------------");
		for(String st:list){
			System.out.println(st);
		}
	}

}

这里我们附上效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值