![1c8d2ff4e90abf60e922c31217aeb325.png](https://i-blog.csdnimg.cn/blog_migrate/d5a43b33d07ac5ce53a36f11e436d6d3.jpeg)
什么是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](https://i-blog.csdnimg.cn/blog_migrate/adc927012f13051084e59b6982a3be01.jpeg)
![b05034ee0b0326e9db0159d7ff9c82d1.png](https://i-blog.csdnimg.cn/blog_migrate/d2021ce390fd38a710a70ae799b70c3e.jpeg)