前言
上次面试时,手写ArrayList竟然翻车,忘了里面的扩容与缩容的条件,再次实现一次,加深印象
源码讲了什么
- 实现了List列表和RandomAccess随机访问接口
- List具有增删改查功能,RandomAccess支持下标访问
- 内部是一个扩容数组,默认大小是10,size=size+size/2
如何实现
- 实现List的add,remove,set,get
- 实现RandomAccess的下标访问
- 实现集合的基本size,isEmpty,toString
- 实现扩容grow,每一增到1.5倍,size=size+size/2
- 缩容方法需要手动调用(内部不会再remove自动调用),使数组容量等于当前元素个数,array=Array(size),size元素个数,array.size时容量
kotlin
fun main() {
val list = MyArrayList()
list.add(1)
list.add(2)
list.add(3)
list.add(0, 2)
list.set(list.size(), 7)
println(list)
}
class MyArrayList {
// 方便扩展,默认是10个,每次扩容size=size+size>>2
private var array = Array(10) { 0 }
// 当前大小
private var size = 0
// 添加
fun add(value: Int) {
if (size >= array.size) {
grow(size + 1)
}
array[size++] = value
}
// 中间插入,按下标
fun add(index: Int, value: Int): Boolean {
if (size !in 0..size) {
return false
}
if (size >= array.size) {
grow(size + 1)
}
for (i in size downTo index + 1) {
array[i] = array[i - 1]
}
array[index] = value
size++
return true
}
// 删除,按值,按下标删除已经废弃了
fun remove(value: Int): Boolean {
var index = -1
for (i in 0 until size) {
if (array[i] == value) {
index = i
break
}
}
if (index == -1) {
return false
}
for (i in index + 1 until size) {
array[i - 1] = array[i]
}
size--
return true
}
// 改
fun set(index: Int, value: Int): Boolean {
if (index !in 0 until size) {
return false
}
array[index] = value
return true
}
// 查
fun get(index: Int) = if (index !in 0 until size) -1 else array[index]
// toString
override fun toString() = StringBuilder().apply {
append("[")
for (i in 0 until size) {
append(if (i == 0) array[i] else ", ${array[i]}")
}
append("]")
}.toString()
// 扩容,添加大量元素时会使用minCapacity
private fun grow(minCapacity: Int) {
var newCapacity = Math.max(minCapacity, array.size + array.size / 2)
val newArray = Array<Int>(newCapacity) { 0 }
for (i in 0 until size) {
newArray[i] = array[i]
}
array = newArray
}
// 缩容方法不用,不写
// 用来判断的empty
fun isEmpty() = size == 0
fun isNotEmpty() = size > 0
fun size() = size
}