在Kotlin开发中如何使用集合详解

作者:一颗香菜 时间:2022-03-06 02:22:30 

关于 Kotlin 开发

使用 Kotlin 开发 Android App 在 Java 工程师群体中变得越来越流行。如果你由于某些原因错过了 Kotlin,我们强烈建议你看一下这篇文章。

对于那些处在技术前沿和喜欢 Kotlin 的开发者来说,本篇文章和他们息息相关。所以,下面就让我们来看一下怎样在 Kotlin 中使用集合吧。

Kotlin中的集合是基于 Java 集合的框架。本篇文章主要讲的是 kotlin.collections 包中的几个特性。

数据处理

Kotlin 中有一个拓展函数的特性,这个特性可以使 Kotlin 标准库(stdlib)支持 JDK 的中的类的方法。举个例子:如果你打开Kotlin 标准库中的 open_Collection.kt 文件,你可以找到很类似于下面这样的方法:


/**
* Returns a list containing only elements matching the given [predicate].
*/
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}

所以,你写的代码可能是下面这个样子:


val originalList = listOf(1, 2, 3, 4, 5, 6)
assertEquals(listOf(2, 4, 6), originalList.filter { it % 2 == 0 })
val originalList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = originalList.firstOrNull { it > 4 }
assertEquals(result, 5)
val originalList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = originalList.getOrElse(12) { 12 }
assertEquals(result, 12)
val originalList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = originalList.dropWhile { it < 5 }
assertEquals(result, listOf(5, 6, 7, 8, 9, 10))
val originalList = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = originalList
   .dropWhile { it < 5 }
   .find { it < 7 }
assertEquals(result, 5)

你需要注意的是:filter和dropWhile 就像其他操作符一样,返回的是一个新的事例。这意味着 originalList 不会改变。

为了更好的理解代码底层到底发生了什么,我们打开源码看一下 listOf() 方法:


/** Returns a new read-only list of given elements. The returned list is serializable (JVM). */
public fun <T> listOf(vararg elements: T): List<T> = if (elements.size > 0) elements.asList() else emptyList()

由于RxJava和 Java 8 的 Stream API 包含类似的方法,所以上面的代码和 RxJava 以及 Stream API很像。 但是由于 Android 工程师不能使用 Stream API,所以他们更多的使用的 RxJava 处理数据的方法来解决这个问题。然后,这种操作并不完全正确,原因在于:RxJava 是一个事件处理库,而不是数据处理。所以你现在可以使用 Kotlin 来解决这个问题而不必担心这些问题。

不可变集合

如果你对不可变对象(immutable object)感觉到很陌生的话,我们建议你先看完这个文档 看完后,在看一下这个。

Kotlin区分可变对象(mutable object)和不可变对象(lists, sets, maps等等)的方法和其他编程语言不一样。在使用Kotlin集合时准确区分这几种两种对象对于避免不必要的错误和 bug 都非常有用。

Kotlin允许像 Java 类似的写法创建 Kotlin 的集合实例。


val list = ArrayList<String>()

这是最简单和整洁的方法. 下面这种方法是最棒的写法:


val list: kotlin.collections.List<String> = java.util.ArrayList()

我创建了一个kotlin.collections.List引用,同时我们也创建了一个不可变的集合。如果你不是很相信的话,那么我们可以看一下源码:


public interface List<out E> : Collection<E> {
// Query Operations
override val size: Int
override fun isEmpty(): Boolean
override fun contains(element: @UnsafeVariance E): Boolean
override fun iterator(): Iterator<E>

// Bulk Operations
override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean

// Positional Access Operations
/**
* Returns the element at the specified index in the list.
*/
public operator fun get(index: Int): E

// Search Operations
/**
* Returns the index of the first occurrence of the specified element in the list, or -1 if the specified
* element is not contained in the list.
*/
public fun indexOf(element: @UnsafeVariance E): Int

/**
* Returns the index of the last occurrence of the specified element in the list, or -1 if the specified
* element is not contained in the list.
*/
public fun lastIndexOf(element: @UnsafeVariance E): Int

// List Iterators
/**
* Returns a list iterator over the elements in this list (in proper sequence).
*/
public fun listIterator(): ListIterator<E>

/**
* Returns a list iterator over the elements in this list (in proper sequence), starting at the specified [index].
*/
public fun listIterator(index: Int): ListIterator<E>

// View
/**
* Returns a view of the portion of this list between the specified [fromIndex] (inclusive) and [toIndex] (exclusive).
* The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.
*/
public fun subList(fromIndex: Int, toIndex: Int): List<E>
}

你看到源码中没 add() 方法,也没有 remove() 方法,同时也没有其他的一些方法去改变这个集合。在这个例子中,实例本身是java.util.ArrayList。 下面我们来通过一个例子来解释为什么:


val list: kotlin.collections.MutableList<String> = java.util.ArrayList()
list.add("string")

你最好在本地的源码中看这例子:


public interface MutableList<E> : List<E>, MutableCollection<E> {
// Modification Operations
override fun add(element: E): Boolean
override fun remove(element: E): Boolean

// Bulk Modification Operations
override fun addAll(elements: Collection<E>): Boolean

/**
* Inserts all of the elements in the specified collection [elements] into this list at the specified [index].
*
* @return `true` if the list was changed as the result of the operation.
*/
public fun addAll(index: Int, elements: Collection<E>): Boolean
override fun removeAll(elements: Collection<E>): Boolean
override fun retainAll(elements: Collection<E>): Boolean
override fun clear(): Unit

// Positional Access Operations
/**
* Replaces the element at the specified position in this list with the specified element.
*
* @return the element previously at the specified position.
*/
public operator fun set(index: Int, element: E): E

/**
* Inserts an element into the list at the specified [index].
*/
public fun add(index: Int, element: E): Unit

/**
* Removes an element at the specified [index] from the list.
*
* @return the element that has been removed.
*/
public fun removeAt(index: Int): E

// List Iterators
override fun listIterator(): MutableListIterator<E>
override fun listIterator(index: Int): MutableListIterator<E>

// View
override fun subList(fromIndex: Int, toIndex: Int): MutableList<E>
}

怎样理解:Java 的 ArrayList 是否和 Kotlin 的 List一样?


val list: kotlin.collections.List<String> = java.util.ArrayList()

实际上,这里并没有什么奇怪的地方. Kotlin 的集合继承了 Java 的 List 的接口。我们可以从 kotlin.collections.Collection.kt 文件中看到:


@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("CollectionsKt")
package kotlin.collections
import kotlin.comparisons.compareValues

正如之前所提的,这个文件包含了所有的集合扩展方法。我们可以看到,我们在 Kotlin 中几乎可以使用 Java CollectionsKT 类中的所有方法.当然,也需要导入 java.util.* 。

让我们来看一下我们在 Java 代码中怎么调用 Kotlin 集合:


java.util.List<Integer> list = kotlin.collections.CollectionsKt.listOf(3, 4, 5);
java.util.List<Integer> filteredList = CollectionsKt.filter(list, item -> item > 4);

你现在可以很清楚的看到 Kotlin 集合是如何使用 Java 的 List 。所有扩展函数都可以作为静态方法访问。

总结

Android 开发语言 Kotlin 是一门非常有趣的语言。它能帮助我们编写更加简洁和安全的代码。初次之外,Kotlin 与 Java 兼容。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

来源:https://juejin.im/post/5abb02136fb9a028d93732c7

标签:kotlin,集合
0
投稿

猜你喜欢

  • Android开发之OpenGL绘制2D图形的方法分析

    2023-05-19 09:59:48
  • android 实现类似微信缓存和即时更新好友头像示例

    2023-12-04 20:47:41
  • SpringMVC多个文件上传及上传后立即显示图片功能

    2021-06-26 12:41:08
  • python 转换 Javascript %u 字符串为python unicode的代码

    2022-07-28 03:15:14
  • Java求解二叉树的最近公共祖先实例代码

    2023-09-14 18:24:56
  • Android中通过view方式获取当前Activity的屏幕截图实现方法

    2021-09-20 09:17:22
  • Android Compose衰减动画Animatable使用详解

    2022-08-26 23:09:42
  • 解决@RequestBody搭配@Data的大坑

    2022-08-29 18:25:35
  • Android中webview与JS交互、互调方法实例详解

    2023-04-30 19:18:27
  • Android Studio一直处于Building的两种解决方法

    2022-06-13 23:05:22
  • Java操作redis设置第二天凌晨过期的解决方案

    2022-11-15 11:40:10
  • Android Studio中的Gradle依赖深入讲解

    2022-09-01 11:16:37
  • QT自定义QTextEdit实现大数据的实时刷新显示功能实例

    2023-05-06 03:18:28
  • 深入理解java中的null“类型”

    2022-07-28 00:41:20
  • SSH框架网上商城项目第23战之在线支付功能实现

    2023-04-22 22:49:19
  • springboot项目配置swagger2示例详解

    2021-09-01 04:24:47
  • C#中三种Timer计时器的详细用法

    2022-12-14 13:52:34
  • arthas排查jvm中CPU占用过高问题解决

    2022-07-15 20:31:49
  • dubbo整合springboot新手入门教程详解

    2022-07-29 21:19:00
  • 解决springboot 部署到 weblogic 中 jar 包冲突的问题

    2021-06-06 11:32:36
  • asp之家 软件编程 m.aspxhome.com