在Kotlin开发中如何使用集合详解
关于Kotlin开发
使用Kotlin开发AndroidApp在Java工程师群体中变得越来越流行。如果你由于某些原因错过了Kotlin,我们强烈建议你看一下这篇文章。
对于那些处在技术前沿和喜欢Kotlin的开发者来说,本篇文章和他们息息相关。所以,下面就让我们来看一下怎样在Kotlin中使用集合吧。
Kotlin中的集合是基于Java集合的框架。本篇文章主要讲的是kotlin.collections包中的几个特性。
数据处理
Kotlin中有一个拓展函数的特性,这个特性可以使Kotlin标准库(stdlib)支持JDK的中的类的方法。举个例子:如果你打开Kotlin标准库中的open_Collection.kt文件,你可以找到很类似于下面这样的方法:
/** *Returnsalistcontainingonlyelementsmatchingthegiven[predicate]. */ publicinlinefunIterable .filter(predicate:(T)->Boolean):List { returnfilterTo(ArrayList (),predicate) }
所以,你写的代码可能是下面这个样子:
valoriginalList=listOf(1,2,3,4,5,6) assertEquals(listOf(2,4,6),originalList.filter{it%2==0}) valoriginalList=listOf(1,2,3,4,5,6,7,8,9,10) valresult=originalList.firstOrNull{it>4} assertEquals(result,5) valoriginalList=listOf(1,2,3,4,5,6,7,8,9,10) valresult=originalList.getOrElse(12){12} assertEquals(result,12) valoriginalList=listOf(1,2,3,4,5,6,7,8,9,10) valresult=originalList.dropWhile{it<5} assertEquals(result,listOf(5,6,7,8,9,10)) valoriginalList=listOf(1,2,3,4,5,6,7,8,9,10) valresult=originalList .dropWhile{it<5} .find{it<7} assertEquals(result,5)
你需要注意的是:filter和dropWhile就像其他操作符一样,返回的是一个新的事例。这意味着originalList不会改变。
为了更好的理解代码底层到底发生了什么,我们打开源码看一下listOf()方法:
/**Returnsanewread-onlylistofgivenelements.Thereturnedlistisserializable(JVM).*/ publicfunlistOf(varargelements:T):List =if(elements.size>0)elements.asList()elseemptyList()
由于RxJava和Java8的StreamAPI包含类似的方法,所以上面的代码和RxJava以及StreamAPI很像。但是由于Android工程师不能使用StreamAPI,所以他们更多的使用的RxJava处理数据的方法来解决这个问题。然后,这种操作并不完全正确,原因在于:RxJava是一个事件处理库,而不是数据处理。所以你现在可以使用Kotlin来解决这个问题而不必担心这些问题。
不可变集合
如果你对不可变对象(immutableobject)感觉到很陌生的话,我们建议你先看完这个文档看完后,在看一下这个。
Kotlin区分可变对象(mutableobject)和不可变对象(lists,sets,maps等等)的方法和其他编程语言不一样。在使用Kotlin集合时准确区分这几种两种对象对于避免不必要的错误和bug都非常有用。
Kotlin允许像Java类似的写法创建Kotlin的集合实例。
vallist=ArrayList()
这是最简单和整洁的方法.下面这种方法是最棒的写法:
vallist:kotlin.collections.List=java.util.ArrayList()
我创建了一个kotlin.collections.List引用,同时我们也创建了一个不可变的集合。如果你不是很相信的话,那么我们可以看一下源码:
publicinterfaceList:Collection { //QueryOperations overridevalsize:Int overridefunisEmpty():Boolean overridefuncontains(element:@UnsafeVarianceE):Boolean overridefuniterator():Iterator //BulkOperations overridefuncontainsAll(elements:Collection<@UnsafeVarianceE>):Boolean //PositionalAccessOperations /** *Returnstheelementatthespecifiedindexinthelist. */ publicoperatorfunget(index:Int):E //SearchOperations /** *Returnstheindexofthefirstoccurrenceofthespecifiedelementinthelist,or-1ifthespecified *elementisnotcontainedinthelist. */ publicfunindexOf(element:@UnsafeVarianceE):Int /** *Returnstheindexofthelastoccurrenceofthespecifiedelementinthelist,or-1ifthespecified *elementisnotcontainedinthelist. */ publicfunlastIndexOf(element:@UnsafeVarianceE):Int //ListIterators /** *Returnsalistiteratorovertheelementsinthislist(inpropersequence). */ publicfunlistIterator():ListIterator /** *Returnsalistiteratorovertheelementsinthislist(inpropersequence),startingatthespecified[index]. */ publicfunlistIterator(index:Int):ListIterator //View /** *Returnsaviewoftheportionofthislistbetweenthespecified[fromIndex](inclusive)and[toIndex](exclusive). *Thereturnedlistisbackedbythislist,sonon-structuralchangesinthereturnedlistarereflectedinthislist,andvice-versa. */ publicfunsubList(fromIndex:Int,toIndex:Int):List }
你看到源码中没add()方法,也没有remove()方法,同时也没有其他的一些方法去改变这个集合。在这个例子中,实例本身是java.util.ArrayList。下面我们来通过一个例子来解释为什么:
vallist:kotlin.collections.MutableList=java.util.ArrayList() list.add("string")
你最好在本地的源码中看这例子:
publicinterfaceMutableList:List ,MutableCollection { //ModificationOperations overridefunadd(element:E):Boolean overridefunremove(element:E):Boolean //BulkModificationOperations overridefunaddAll(elements:Collection ):Boolean /** *Insertsalloftheelementsinthespecifiedcollection[elements]intothislistatthespecified[index]. * *@return`true`ifthelistwaschangedastheresultoftheoperation. */ publicfunaddAll(index:Int,elements:Collection ):Boolean overridefunremoveAll(elements:Collection ):Boolean overridefunretainAll(elements:Collection ):Boolean overridefunclear():Unit //PositionalAccessOperations /** *Replacestheelementatthespecifiedpositioninthislistwiththespecifiedelement. * *@returntheelementpreviouslyatthespecifiedposition. */ publicoperatorfunset(index:Int,element:E):E /** *Insertsanelementintothelistatthespecified[index]. */ publicfunadd(index:Int,element:E):Unit /** *Removesanelementatthespecified[index]fromthelist. * *@returntheelementthathasbeenremoved. */ publicfunremoveAt(index:Int):E //ListIterators overridefunlistIterator():MutableListIterator overridefunlistIterator(index:Int):MutableListIterator //View overridefunsubList(fromIndex:Int,toIndex:Int):MutableList }
怎样理解:Java的ArrayList是否和Kotlin的List一样?
vallist:kotlin.collections.List=java.util.ArrayList()
实际上,这里并没有什么奇怪的地方.Kotlin的集合继承了Java的List的接口。我们可以从kotlin.collections.Collection.kt文件中看到:
@file:kotlin.jvm.JvmMultifileClass @file:kotlin.jvm.JvmName("CollectionsKt") packagekotlin.collections importkotlin.comparisons.compareValues
正如之前所提的,这个文件包含了所有的集合扩展方法。我们可以看到,我们在Kotlin中几乎可以使用JavaCollectionsKT类中的所有方法.当然,也需要导入java.util.*。
让我们来看一下我们在Java代码中怎么调用Kotlin集合:
java.util.Listlist=kotlin.collections.CollectionsKt.listOf(3,4,5); java.util.List filteredList=CollectionsKt.filter(list,item->item>4);
你现在可以很清楚的看到Kotlin集合是如何使用Java的List。所有扩展函数都可以作为静态方法访问。
总结
Android开发语言Kotlin是一门非常有趣的语言。它能帮助我们编写更加简洁和安全的代码。初次之外,Kotlin与Java兼容。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。