清空arraylist_实现JS简易版的ArrayList

1c8d2ff4e90abf60e922c31217aeb325.png

什么是ArrayList?

可以简单的认为是一个动态数组;实际上ArrayList就是用数组实现的,长度不够时,拷贝当前数组到一个新的长度更大的数组;

因此主要是了解下它的动态扩容。

class ArrayList {
	constructor() {
		// 默认的list容量大小
		this.defaultCapacity = 10
		// list中元素的个数
		this.size = 0
		// 数据集,存储的元素支持泛型
		this.data = new Array(this.defaultCapacity)
	}

	/**
	 * 获取list element个数
	 * @returns {number}
	 */
	length() {
		return this.size
	}

	/**
	 * 检查list是否为空
	 * @returns {boolean}
	 */
	isEmpty() {
		return this.size === 0
	}

	/**
	 * 检查一个元素是否存在list中
	 * @param {any} element
	 * @returns {boolean}
	 */
	contains(element) {
		return this.indexOf(element) !== -1
	}

	/**
	 * 返回element在list中第一次出现的索引位置,从前往后扫描,不存在返回-1
	 * @param {any} element
	 * @returns {number}
	 */
	indexOf(element) {
		for (let i = 0; i < this.size; i++) {
			if (Object.is(element, this.data[i])) {
				return i
			}
		}
		return -1
	}

	/**
	 * 返回element在list中第一次出现的索引位置,从后往前扫描,不存在返回-1
	 * @param {any} element
	 * @returns {number}
	 */
	lastIndexOf(element) {
		for (let i = this.size; i >= 0; i--) {
			if (Object.is(element, this.data[i])) {
				return i
			}
		}
		return -1
	}

	/**
	 * 根据索引查找对应元素
	 * @param {number} index
	 * @returns {any}
	 */
	get(index) {
		this.checkBoundExclusive(index)
		return this.data[index]
	}

	/**
	 * 修改索引位置中的值
	 * @param {number} index
	 * @param {any} element
	 * @returns {any}
	 */
	set(index, element) {
		this.checkBoundExclusive(index)
		const oldValue = this.data[index]
		this.data[index] = element
		return oldValue
	}

	/**
	 * 添加element到list
	 * @param {any} element
	 * @returns {boolean}
	 */
	add(element) {
		if (this.size === this.data.length) {
			this.ensureCapacity(this.size + 1)
		}
		this.data[this.size++] = element
		return true
	}

	/**
	 * 在指定索引位置插入element
	 * @param {number} index
	 * @param {any} element
	 */
	insert(index, element) {
		this.checkBoundExclusive(index)
		if (this.size === this.data.length) {
			this.ensureCapacity(this.size + 1)
		}
		if (index !== this.size) {
			this.arrayCopy(
				this.data,
				index,
				this.data,
				index + 1,
				this.size - index
			)
		}
		this.data[index] = element
		this.size++
	}

	/**
	 * 数组拷贝
	 * @param {array} sourceData 源list
	 * @param {number} sourceStartIndex 源起始位置
	 * @param {array} targetData 目标list
	 * @param {number} targetStartIndex 目标起始位置
	 * @param {number} length 操作的长度
	 */
	arrayCopy(
		sourceData,
		sourceStartIndex,
		targetData,
		targetStartIndex,
		length
	) {
        if (targetStartIndex <= sourceStartIndex) {
            // 往前移
            for (
				let i = targetStartIndex;
				i <= targetStartIndex + length;
				i++
			) {
				targetData[i] = sourceData[sourceStartIndex++]
			}
        
        } else {
            // 往后移
            for (
				let i = targetStartIndex + length;
				i >= sourceStartIndex;
				i--
			) {
				targetData[i] = sourceData[i - 1]
			}
        }
	}

	/**
	 * 移除指定索引位置元素
	 * @param {number} index
	 */
	remove(index) {
		this.checkBoundExclusive(index)
		const r = this.data[index]
		if (index !== --this.size) {
			this.arrayCopy(this.data, index + 1, this.data, index, this.size - index)
		}
		this.data[this.size] = null
		return r
	}

	/**
	 * 清空list
	 */
	clear() {
		this.data = new Array[this.defaultCapacity]()
		this.size = 0
	}

	/**
	 * 检查数组是否越界
	 * @param {number} index
	 */
	checkBoundExclusive(index) {
		if (index >= this.size) {
			throw new Error(`Index: ${index} , Size: ${(this, this.size)}`)
		}
	}
	/**
	 * 动态扩容
	 * @param {number} minCapacity
	 */
	ensureCapacity(minCapacity) {
		if (minCapacity > this.data.length) {
			const newData = new Array(
				Math.max(2 * this.defaultCapacity, minCapacity)
            )
			this.arrayCopy(this.data, 0, newData, 0, this.size)
			this.data = newData
		}
	}
}


// test case

const list = new ArrayList()
console.log('是否为空', list.isEmpty())
console.log('当前长度', list.length())
list.add(1)
list.add(2)
list.add(3)
list.add(4)
list.add(5)
list.add(6)
list.add(7)
list.add(8)
list.add(9)
list.add(10)
console.log("当前长度", list.length())
list.add(11)
console.log(list)
// console.log(list.contains(12))
// console.log(list.indexOf(2), list)
// console.log(list.lastIndexOf(10))
// console.log(list)
list.add(12)
list.insert(11, '替换之前的11')
console.log(list)
list.remove(10)
console.log(list)
list.insert(0, '替换之前的0')
console.log(list)

福利

问末附上几个脑图。

04f979acae550dbce3f4cc40b0cafe65.png

b05034ee0b0326e9db0159d7ff9c82d1.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值