一个不会产生数组溢出的数组使用扩容方案
看源码里面存在这样的一个函数
源码里面array的容量始终为2^n
private fun Array<Any?>.getBufferAt(index: Long) = get(index.toInt() and (size - 1))
private fun Array<Any?>.setBufferAt(index: Long, item: Any?) = set(index.toInt() and (size - 1), item)
什么意思呢?
我们知道a % b = a & (b - 1)
在b为2^n时成立。
因为源码里面array的容量始终为2^n,所以上述get 和 set 的index均为 a % b
。为什么这么写呢?
下面我们写个例子看看结果🙆♀️
val intArray = Array(2) { it + 1 }
for (i in 0..10){
println(intArray[i and (intArray.size - 1)])
}
//结果
1
2
1
2
1
2
1
2
1
2
1
看得出,取余的时候,永远就没有数组越界了。😮
但是,使用位运算符的方式,只能在b为2^n时成立,所以如果想要任何适合都可以使用的话,可以直接取余不通过位运算符。
val intArray = Array(3) { it + 1 }
for (i in 0..10){
println(intArray[i % intArray.size])
}
//结果
1
2
3
1
2
3
1
2
3
1
2
总结
如果你不想自己封装的代码在数组这一块出现数组越界异常的话,可以使用余数做处理。
如果你确定自己的数组容量始终以时2的倍数,可以直接使用位运算符进行取余操作。否则可以直接取余。👀
看源码看到的,分享一下 哈哈哈哈。