手写底层List源码

概述

此文章属于个人看过底层源码以后、自己手写实现的学习文章、如有不对或者考虑的不够具体的方面、请多指教、相互学习、谢谢

ArrayList源码

1、默认的无参构造方法、默认数组大小是10、如果指定了数组大小、就使用指定了的大小、(注意如果指定的大小是小于0的话、就抛出个异常)
2、添加元素、如果达到了目前的定义的初始长度、比如10、就需要扩容、还有元素数+1
3、扩容的时候、如果自定义了初始大小、并且是0或者是1、就会在Arrays.copyOf( data, data.length+(data.length>>1))、0>>1还是0、还有1>>1还是1 然后这个在放元素的时候就会报错、可以判断下、然后不用右移、直接给个任意的大小不是0就行、
4、根据索引添加元素的时候、索引是否越界问题>size 还有小于0、抛异常、然后就是把元素从索引位置右移一个、还有扩容问题
5、根据索引查找元素、
6、看list中是否包含xxx元素、
7、获取指定下标元素、
8、移除指定位置元素、

class ArrList {
	// 用于存储数据
	private Object[] data;
	// 记录元素个数
	private int size = 0;
	public ArrList() {
		this.data = new Object[10];
	}
	public ArrList(int initialCapacity) {
		if (initialCapacity < 0)
			throw new IllegalArgumentException();
		this.data = new Object[initialCapacity];
	}
	// 添加元素
	public void add(Object o) {
		// 判断是否需要扩容
		if (size >= data.length)
			grow();
		data[size] = o;
		size++;
	}
	// 用于扩容
	private void grow() {
		if (data.length <= 1)
			data = Arrays.copyOf(data, data.length + 1);
		else
			data = Arrays.copyOf(data, data.length + (data.length >> 1));
	}
	// 插入
	public void add(int index, Object o) {
		// 判断下标越界
		if (index > size || index < 0)
			throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
		// 判断扩容
		if (size >= data.length)
			grow();
		// for(int i = size - 1; i >= index; i--){
		// data[i + 1] = data[i];
		// }
		System.arraycopy(data, index, data, index + 1, size - index);
		data[index] = o;
		size++;
	}
	// 清空列表
	public void clear() {
		data = new Object[10];
		size = 0;
	}
	// 判断是否包含指定的元素
	public boolean contains(Object o) {
		return indexOf(o) != -1;
	}
	// 判断下标是否越界
	private void outOfBounds(int index) {
		if (index >= size || index < 0)
			throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
	}
	// 获取指定下标上的元素
	public Object get(int index) {
		outOfBounds(index);
		return data[index];
	}
	// 获取指定元素第一个出现的下标
	// indexOf(null)
	public int indexOf(Object o) {
		// 为了防止出现空指针异常,需要判断参数是否位null
		// 如果o为null并且data[i]也为null
		for (int i = 0; i < size; i++) {
			if (o == data[i] || o != null && o.equals(data[i])) {
				return i;
			}
		}
		return -1;
	}
	public boolean isEmpty() {
		return size <= 0;
	}
	// 获取指定的元素最后一次出现的位置
	public int lastIndexOf(Object o) {
		for (int i = size - 1; i >= 0; i--) {
			if (o == data[i] || o != null && o.equals(data[i]))
				return i;
		}
		return -1;
	}
	// 移除指定下标上的元素
	public void remove(int index) {
		outOfBounds(index);
		// for (int i = index; i < size - 1; i++) {
		// data[i] = data[i + 1];
		// }
		System.arraycopy(data, index + 1, data, index, size - (index + 1));
		size--;
	}
	// 移除指定的元素
	public void remove(Object o) {
		// 找到这个元素第一次出现的位置
		int index = indexOf(o);
		// 判断是否找到了这个元素
		if (index != -1)
			remove(index);
	}
	// 替换
	public void set(int index, Object o) {
		outOfBounds(index);
		data[index] = o;
	}
	public int size() {
		return size;
	}
	// 截取子列表
	public ArrList subList(int fromIndex, int toIndex) {
		if (fromIndex < 0 || toIndex < 0 || toIndex > size)
			throw new IllegalArgumentException();
		int size = toIndex - fromIndex;
		if (size < 0)
			throw new IllegalArgumentException();
		ArrList sub = new ArrList(size);
		System.arraycopy(data, fromIndex, sub.data, 0, size);
		sub.size = size;
		return sub;
	}
	public Object[] toArray() {
		Object[] newArr = new Object[size];
		System.arraycopy(data, 0, newArr, 0, size);
		return newArr;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for (int i = 0; i < size; i++) {
			sb.append(data[i]).append(", ");
		}
		String str = sb.toString();
		if (size > 0)
			str = str.substring(0, str.length() - 2);
		return str += "]";
	}
}

ArrayList源码

class LinkList {
	private int size = 0;
	private Node first;
	private Node last;
	// 添加元素
	public void add(Object o) {
		// 创建一个新的节点存储元素
		Node node = new Node(null, o, null);
		// 判断是否是第一个节点
		if (size == 0) {
			// 将头节点指向新节点
			this.first = node;
		} else {
			// 将原来尾节点的下一位指向新节点
			this.last.next = node;
			// 将新节点的上一位指向原来的尾节点
			node.prev = last;
		}
		// 将尾节点挪到新节点上
		this.last = node;
		size++;
	}
	// 插入
	public void add(int index, Object o) {
		// 判断下标是否越界
		if (index > size || index < 0)
			throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
		// 插在尾部相当于添加
		if (index == size) {
			add(o);
			return;
		}
		Node node = new Node(null, o, null);
		// 插在头部
		if (index == 0) {
			// 新节点的下一位是原来的头节点
			node.next = this.first;
			// 原来的头节点的上一位是新的节点
			this.first.prev = node;
			// 将头结点挪到新节点上
			this.first = node;
		} else {
			// 找到指定下标对应的节点
			Node no = getNode(index);
			// 原节点的上一位的下一个节点是新节点
			no.prev.next = node;
			// 新节点的上一位是原节点的上一位
			node.prev = no.prev;
			// 新节点的下一位是原节点
			node.next = no;
			// 原节点的上一位是新节点
			no.prev = node;
		}
		size++;
	}
	private Node getNode(int index) {
		Node node = this.first;
		for (int i = 0; i < index; i++) {
			node = node.next;
		}
		return node;
	}
	public void clear() {
		this.first = this.last = null;
		size = 0;
	}
	public boolean contains(Object o) {
		return indexOf(o) != -1;
	}
	// 判断下标是否越界
	private void outOfBounds(int index) {
		if (index >= size || index < 0)
			throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
	}
	public Object get(int index) {
		outOfBounds(index);
		return getNode(index).data;
	}
	public int indexOf(Object o) {
		// 指向头节点
		Node node = this.first;
		int index = 0;
		// 判断该节点是否为空
		while (node != null) {
			// 判断该节点的数据和指定的数据是否相等
			if (o == node.data || o != null && o.equals(node.data)) {
				return index;
			}
			// 如果该节点的数据和指定的数据不相等,则挪到下一个节点上
			node = node.next;
			index++;
		}
		return -1;
	}
	public boolean isEmpty() {
		return size <= 0;
	}
	public int lastIndexOf(Object o) {
		Node node = this.last;
		int index = size - 1;
		while (node != null) {
			if (o == node.data || o != null && o.equals(node.data))
				return index;
			node = node.prev;
			index--;

		}
		return -1;
	}
	public void remove(int index) {
		outOfBounds(index);
		// 判断是否是只有一个节点
		if (size == 1) {
			this.first = this.last = null;
		} else {
			// 是否是头节点
			if (index == 0) {
				this.first = this.first.next;
				this.first.prev = null;
			} else if (index == size - 1) {
				this.last = this.last.prev;
				this.last.next = null;
			} else {
				// 找到这个节点
				Node node = this.getNode(index);
				node.prev.next = node.next;
				node.next.prev = node.prev;
			}
		}
		size--;
	}
	public void remove(Object o) {
		int index = indexOf(o);
		if (index != -1)
			remove(index);
	}
	public void set(int index, Object o) {
		outOfBounds(index);
		getNode(index).data = o;
	}
	public int size() {
		return size;
	}
	public LinkList subList(int fromIndex, int toIndex) {
		if (fromIndex < 0 || toIndex < 0 || toIndex > size || toIndex < fromIndex)
			throw new IllegalArgumentException();
		int size = toIndex - fromIndex;
		LinkList sub = new LinkList();
		Node node = this.getNode(fromIndex);
		for (int i = 0; i < size; i++) {
			sub.add(node.data);
			node = node.next;
		}
		return sub;
	}
	public Object[] toArray() {
		Object[] os = new Object[size];
		int i = 0;
		Node node = this.first;
		while (node != null) {
			os[i] = node.data;
			node = node.next;
			i++;
		}
		return os;
	}
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		Node node = this.first;
		while (node != null) {

			sb.append(node.data).append(", ");
			node = node.next;
		}
		String str = sb.toString();
		if (size != 0)
			str = str.substring(0, str.length() - 2);
		return str += "]";
	}
	private class Node {
		Node prev;
		Object data;
		Node next;
		public Node(Node prev, Object data, Node next) {
			super();
			this.prev = prev;
			this.data = data;
			this.next = next;
		}
	}
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值