предисловие
Как мы все знаем, в kotlin есть ArrayList<Int>, Array<Int>, IntArray, но в чем между ними разница, почему так много примерно одинаковых типов?
текст
Давайте сначала посмотрим на их типы относительно jvm
ArrayList<Целое> = ArrayList<Целое>
Массив<Целое> = Целое[]
IntArray = интервал []
Видно, что первые два типа используют тип упаковки int Integer, в то время как IntArray использует базовый тип данных int.Как вы можете видеть в следующей статье, производительность типа упаковки хуже из-за автоматической упаковки и распаковки jvm. (Во времени и пространстве). [Основная проблема числового типа Котлина: это объект? Или базовый тип данных?]
Но у ArrayList<Int> есть переменный верхний предел (механизм расширения), а у IntArray нет. Что нам делать, если мы хотим, чтобы IntArray можно было расширять, а также использовать базовые типы данных (более высокая производительность)? Мы можем написать базовые данные введите как ArrayList<Int> следующим образом:
ps: проект с открытым исходным кодом: lttttttttttt/DataStructure: (обычно используемые пользовательские структуры данных) (github.com)
package com.lt.androidkj.utils.collection
/**
* creator: lt 2021/11/10 [email protected]
* effect : 性能更好的ArrayList<Int>,线程不安全
* warning:[initSize]初始化容量
*/
class IntArrayList(initSize: Int = 10) : RandomAccess {
constructor(intArray: IntArray) : this(intArray.size) {
data = intArray.copyOf()
size = data.size
}
constructor(intArrayList: IntArrayList) : this(intArrayList.data.copyOf(intArrayList.size))
constructor(list: Collection<Int>) : this(list.size) {
list.forEach(::add)
}
//内部数据
private var data: IntArray = IntArray(initSize) { 0 }
/**
* 获取内部的总数量
*/
var size: Int = 0
private set
/**
* 获取数据
*/
operator fun get(index: Int): Int {
if (index >= size)
throw IndexOutOfBoundsException("size = $size ,the index = $index")
return data[index]
}
/**
* 获取数据,如果索引越界,就返回else的返回值
*/
inline fun getOrElse(index: Int, defaultValue: () -> Int): Int {
if (index !in 0 until size)
return defaultValue()
return get(index)
}
/**
* 获取数据,如果索引越界,就返回null
*/
fun getOrNull(index: Int): Int? {
if (index !in 0 until size)
return null
return get(index)
}
/**
* 添加数据
* 扩容机制:容量翻倍
*/
fun add(element: Int) {
if (size == data.size)
data = data.copyOf(data.size * 2)
data[size] = element
size++
}
/**
* 根据数据移除
*/
fun removeElement(element: Int) {
val indexOf = indexOf(element)
if (indexOf >= 0) {
removeAtIndex(indexOf)
}
}
/**
* 根据索引移除
*/
fun removeAtIndex(index: Int) {
if (index >= size)
throw IndexOutOfBoundsException("size = $size ,the index = $index")
val numMoved = size - index - 1
if (numMoved > 0)
System.arraycopy(data, index + 1, data, index, numMoved)
size--
}
/**
* 移除第一个位置
*/
fun removeFirst() = removeAtIndex(0)
/**
* 移除最后一个位置
*/
fun removeLast() = removeAtIndex(size - 1)
/**
* 设置某个索引的数据
*/
operator fun set(index: Int, element: Int): Int {
if (index >= size)
throw IndexOutOfBoundsException("size = $size ,the index = $index")
val oldElement = get(index)
data[index] = element
return oldElement
}
/**
* 如果[index]没有超过size就设置,否则丢弃该次修改
*/
fun setOrDiscard(index: Int, element: Int) {
if (index >= size || index < 0) return
set(index, element)
}
/**
* 获取内部是否没有数据
*/
fun isEmpty(): Boolean = size == 0
/**
* 获取对应数据的索引,如果没有则返回-1
*/
fun indexOf(element: Int): Int {
forEachIndexed { index, datum ->
if (element == datum)
return index
}
return -1
}
/**
* 从后往前获取对应数据的索引,如果没有则返回-1
*/
fun lastIndexOf(element: Int): Int {
forEachReversedIndexed { index, datum ->
if (element == datum)
return index
}
return -1
}
/**
* 获取是否存在对应数据
*/
operator fun contains(element: Int): Boolean = indexOf(element) >= 0
/**
* 获取迭代器
*/
operator fun iterator(): MutableIterator<Int> = object : MutableIterator<Int> {
private var index = 0
override fun hasNext(): Boolean = size > index
override fun next(): Int = get(index++)
override fun remove() = removeAtIndex(--index)
}
/**
* 遍历的方法
* ps:使用forEach系列比for性能好(因为迭代器的next()返回的是对象)
*/
inline fun forEach(action: (element: Int) -> Unit) {
forEachIndexed { _, element -> action(element) }
}
inline fun forEachIndexed(action: (index: Int, element: Int) -> Unit) {
var index = 0
while (index < size) {
action(index, get(index))
index++
}
}
/**
* 倒序遍历
*/
inline fun forEachReversedIndexed(action: (index: Int, element: Int) -> Unit) {
var index = size - 1
while (index >= 0) {
action(index, get(index))
index--
}
}
/**
* 获取一段IntArrayList
*/
fun subList(fromIndex: Int, toIndex: Int): IntArrayList {
if (toIndex > size)
throw IndexOutOfBoundsException("size = $size ,the toIndex = $toIndex")
return IntArrayList(data.copyOfRange(fromIndex, toIndex))
}
/**
* 安全的subList,索引超限部分不会返回内容
*/
fun subListWithSafe(fromIndex: Int, toIndex: Int): IntArrayList =
IntArrayList(data.copyOfRange(maxOf(0, fromIndex), minOf(size, toIndex)))
/**
* 批量添加数据
*/
fun addAll(elements: Collection<Int>) {
elements.forEach(::add)
}
fun addAll(elements: IntArrayList) {
addAll(elements.data.copyOf(elements.size))
}
fun addAll(elements: IntArray) {
elements.forEach(::add)
}
fun addAllNotNull(elements: Collection<Int?>?) {
elements?.forEach {
if (it != null)
add(it)
}
}
/**
* 批量移除数据
*/
fun removeAll(elements: Collection<Int>) {
elements.forEach(::removeElement)
}
fun removeAll(elements: IntArrayList) {
removeAll(elements.data.copyOf(elements.size))
}
fun removeAll(elements: IntArray) {
elements.forEach(::removeElement)
}
/**
* 清空数据
*/
fun clear() {
size = 0
}
/**
* 转换数据结构
*/
fun toIntArray() = data.copyOf(size)
fun toMutableList() = toIntArray().toMutableList()
override fun toString(): String {
return "[" + data.copyOf(size).joinToString(",") + "]"
}
}
fun intArrayListOf(vararg elements: Int): IntArrayList = IntArrayList(elements)
Его производительность лучше, базовый тип данных используется внутри, и он поддерживает автоматическое расширение.Метод использования в основном такой же, как у ArrayList.
Если вы хотите установить Double, вам нужно только сделать копию и изменить Int на Double
конец