1. 手写一个MyArrayList
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是支持动态扩容,即没有固定大小的限制,我们可以添加或删除元素。
ArrayList 本质是数组,故具有查询快,增删慢的特点
- add():新增时需要考虑扩容的因素。这个是区别数组的核心方法
- get(): 非常好地体现出下标查找的优势,故查询快
- remove():体现出数组的缺点,删除一个元素,后面的元素需整体前移,故删除慢
优点:
- 1、根据下标遍历元素效率较高。
- 2、根据下标访问元素效率较高。
- 3、在数组的基础上封装了对元素操作的方法。
- 4、可以自动扩容。
缺点:
- 1、插入和删除的效率比较低。
- 2、根据内容查找元素的效率较低。
扩容规则:每次扩容现有容量的50%。
2. 自定义 MyArrayList
2.1 IMyList.java
主要实现IMyList定义的函数,例如add、get、remove、contains
IMyList.java
package com.sufadi.study.arrayList
interface IMyList {
fun size(): Int
fun isEmpty(): Any
// 是否存在
fun contains(objects: Any): Boolean
fun clear()
fun add(objects: Any): Boolean
fun remove(index: Int): Boolean
fun get(index: Int): Any?
}
2.1 MyArrayList.java
add():新增时需要考虑扩容的因素。这个是区别数组的核心方法 get(): 非常好地体现出下标查找的优势,故查询快 remove():体现出数组的缺点,删除一个元素,后面的元素需整体前移,故删除慢
package com.sufadi.study.arrayList
import java.lang.Exception
/**
* 学习文章来源
* https://blog.csdn.net/weixin_40834464/article/details/82750466
*/
class MyArrayList @JvmOverloads constructor(private var capacitySize: Int = DEFAULT_CAPACITY) : IMyList {
// JDK 源码规定的长度
companion object {
internal val DEFAULT_CAPACITY = 10
}
var size: Int = 0
private var elementDatas: Array<Any?>
init {
elementDatas = arrayOfNulls(capacitySize)
}
override fun add(objects: Any): Boolean {
// 数组扩容函数:超出就扩容1倍
ensureCapacity()
elementDatas[size] = objects
size++
return false
}
override fun contains(objects: Any) : Boolean{
for (data in elementDatas) {
if (data == objects) {
return true
}
}
return false
}
override fun get(index: Int): Any? {
// 对索引下标进行合法性检查
rangeCheck(index)
return elementDatas[index]
}
override fun remove(index: Int): Boolean {
// 对索引下标进行合法性检查
rangeCheck(index)
val offsetSize = size - index - 1
/**
* 思路: 删除1个,整体前移1位,最后一位置空
*
* src:要复制的数组(源数组):elementDatas
* srcPos:复制源数组的起始位置:index + 1
* dest:目标数组:elementDatas
* destPos:目标数组的下标位置:被删除的位置为起点
* length:要复制的长度:offsetSize
*/
println(" remove index=$index, 数组整体移动1位,将index(${index+1} 到${index+1+offsetSize})区域整体放到(${index} 到 ${index+offsetSize})区域")
System.arraycopy(elementDatas, index + 1, elementDatas, index, offsetSize)
elementDatas[size - 1] = null
return true
}
override fun isEmpty(): Any {
return size == 0
}
override fun clear() {
elementDatas = arrayOf(capacitySize)
size = 0
}
override fun size(): Int {
return size
}
/**
* 数组扩容函数:超出就扩容1倍,数组复制实现
*/
private fun ensureCapacity() {
if (size == elementDatas.size) {
val newArray = arrayOfNulls<Any?>(size*2)
println(" 当前数据容量不够用,需要扩容,新的数据大小为:${newArray.size}")
System.arraycopy(elementDatas, 0, newArray, 0, elementDatas.size)
elementDatas = newArray
}
}
/**
* 对索引下标进行合法性检查
*/
private fun rangeCheck(index: Int) {
if (index < 0 || index >= size) {
try {
throw Exception()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
3 示例调用
3.1 main()
package com.sufadi.study.arrayList
class MyArrayListRunTest {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val myArrayList = MyArrayList()
println("1. 测试add()函数: 填充1~10的数据")
for (i in 1..10) {
myArrayList.add(i)
}
println(" 查看数组的大小:${myArrayList.size}")
for (i in 0 until myArrayList.size) {
println(" Index = $i, get()函数:${myArrayList.get(i)}")
}
println("2. 测试扩容ensureCapacity(): 填充超过默认扩容大小的数据,例如hello world")
myArrayList.add("hello world")
println(" 查看数组的大小:${myArrayList.size}")
for (i in 0 until myArrayList.size) {
println(" Index = $i, get()函数:${myArrayList.get(i)}")
}
println("3. 测试删除remove()函数,例如删除index 3")
myArrayList.remove(3)
println(" 查看数组的大小:${myArrayList.size}")
for (i in 0 until myArrayList.size) {
println(" Index = $i, get()函数:${myArrayList.get(i)}")
}
}
}
}
3.2 运行结果
1. 测试add()函数: 填充1~10的数据
查看数组的大小:10
Index = 0, get()函数:1
Index = 1, get()函数:2
Index = 2, get()函数:3
Index = 3, get()函数:4
Index = 4, get()函数:5
Index = 5, get()函数:6
Index = 6, get()函数:7
Index = 7, get()函数:8
Index = 8, get()函数:9
Index = 9, get()函数:10
2. 测试扩容ensureCapacity(): 填充超过默认扩容大小的数据,例如hello world
当前数据容量不够用,需要扩容,新的数据大小为:20
查看数组的大小:11
Index = 0, get()函数:1
Index = 1, get()函数:2
Index = 2, get()函数:3
Index = 3, get()函数:4
Index = 4, get()函数:5
Index = 5, get()函数:6
Index = 6, get()函数:7
Index = 7, get()函数:8
Index = 8, get()函数:9
Index = 9, get()函数:10
Index = 10, get()函数:hello world
3. 测试删除remove()函数,例如删除index 3
remove index=3, 数组整体移动1位,将index(4 到11)区域整体放到(3 到 10)区域
查看数组的大小:11
Index = 0, get()函数:1
Index = 1, get()函数:2
Index = 2, get()函数:3
Index = 3, get()函数:5
Index = 4, get()函数:6
Index = 5, get()函数:7
Index = 6, get()函数:8
Index = 7, get()函数:9
Index = 8, get()函数:10
Index = 9, get()函数:hello world
Index = 10, get()函数:null
Process finished with exit code 0
|