Kotlin学习笔记-基本类型、集合等
基本数据类型和类型系统
Kotlin类型层级结构,最顶层Any?,最底层Nothing。
Unit与Nothing
Unit类型表达式计算结果的返回类型是Unit。Nothing类型的表达式计算结果是永远不会返回(跟Java中的void相同)
集合
世间本无集合(只有数组)。
但有人想要,于是就用数组创造了集合类。
有人想要自动扩展容量的数组,于是有了List。
有人想要元素不重复的数组,于是有了Set。
有人想要有序的数组,于是有了TreeSet、TreeList。
有人想要通过复杂对象(而不仅仅是简单的下表)来查找另一个对象的关联数组,于是就有了Map。
集合-List
Iterable<-Collection<-List(List、MutableList)
1. 过滤操作函数-takeIf
当takeOf{满足条件,返回this对象(可以使用it),否则返回null}
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
val list2 = listOf(1, 4, 5)
list2.takeIf { (it[1]>3) } // [1, 4, 5]
list2.takeIf { (it[1]>4) } // null
2. 过滤操作函数-filter
过滤出满足条件的元素组成的子集合。
val list2 = listOf(1, 4, 5)
list2.filter { it>4 } // [4]
list2.filter { it>5 } // []
其它:
firstOrNull–返回符合条件的第一个元素,没有返回null;
3. 映射操作函数-map
将集合中的元素通过转换函数transform映射后的结果,存到一个集合中返回
val list2 = listOf(1, 4, 5)
list2.map { it*2 } //[2, 8, 10]
4. 分组操作函数-groupBy
将集合中的元素按照条件选择器keySelector分组,并返回Map。
public inline fun <T, K> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>> {
return groupByTo(LinkedHashMap<K, MutableList<T>>(), keySelector)
}
val list3 = listOf("abc","a", "abc","abcd","abcde")
println(list3.groupBy { it.length }) // {3=[abc, abc], 1=[a], 4=[abcd], 5=[abcde]}
集合-Set
元素不重复,分为Set、MutableSet
集合-Map
(K-V pair)键值对,没有继承Collection接口;Kotlin仅对基于Java为Map增加了一些扩展;访问Map的元素的属性有:entries、keys、values、size。
创建Map
mapOf(pair:Pair<K,V>):Map<K,V>//使用二元组Pair创建一个只读Map
mutableMapOf(vararg pairs:Pair<K,V>):MutableMap<K,V> // 创建一个可编辑的MutableMap对象
private fun testMap() {
val map = mapOf(1 to "x", 2 to "y")
println(map) //{1=x, 2=y}
println(map.get(4)) //null
println(map[2])// y
}
操作符函数-getOrElse(key:K,defaultValue:()->V):V
通过key获取值,当没有值可以设置默认值。
val map = mapOf(1 to "x", 2 to "y")
val orElse = map.getOrElse(key = 3, defaultValue = { "4" })
val orDefault = map.getOrDefault(key = 3, defaultValue = "4")
println(orElse) //4
println(orDefault) //4
操作符函数-getValue(key:K):V
当没有匹配的key时,会抛异常,所以慎用此法。
Caused by: java.util.NoSuchElementException: Key 3 is missing in the map.
at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:19)
at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:270)
操作符函数-加法运算
public operator fun <K, V> Map<out K, V>.plus(pair: Pair<K, V>): Map<K, V>
= if (this.isEmpty()) mapOf(pair) else LinkedHashMap(this).apply { put(pair.first, pair.second) }
val mutableMap = mutableMapOf(1 to "x", 2 to "y")
val map1 = mutableMap + Pair(3, "z")
println(map1)// {1=x, 2=y, 3=z}
泛型
泛型即“参数化类型”,就是将类型由原来的具体类型参数化。
型变(Variant)(概念比较绕)
三种基本形态:协变(Covariant)、逆变、不变;
// <? extends T> Animal是一个动物父类,Dog是子类
List<? extends Animal> list1 = new ArrayList<>();
list1.add(new Dog()); //错误,提示 add to list cannot be applied
List<Animal> list2 = new ArrayList<>();
list2.add(new Dog());
list1= list2; // 可以,在Kolin中有读取数据的意思,对应out T
// <? super T>
List<? super Animal> list3 = new ArrayList<>();
list3.add(new Dog());// 可以,在Kolin中有写入数据的意思,对应in T
我们把父类型(F,Father)与子类型(C,Child)的关系,简记为F<|C。
把List操作记为f(F),f(C)。
当F <|C 时,如果有f(F) <| f(C),那么f叫做协变;
当F <|C 时,如果f(C) <| f(F),那么f叫做逆变。
如果上面两种关系都不成立则叫不变。
Kotlin中的泛型,引入消费者和设计师概念,即PECS概念(producer-extends, consumer-super)
Java | Kotlin | remark-Java | remark-Kotlin |
---|---|---|---|
? extends T | out T | 子类型上界限定符,实现了泛型的协变 | 生产数据的对象(读取数据) |
? super T | in T | 超类型下界限定符,实现了泛型的逆变 | 消费数据的对象(写入数据) |
? | * |
其它
Kotlin集成Gradle开发
Gradle是一个项目自动化构建工具,基于Ant和Maven,它使用Groovy DSL(领域特定语言)来声明项目设置,抛弃了基于XML的各种繁琐配置。我们使用kotlin-gradle插件来构建Kotlin语言的Gradle项目。
使用Kotlin DSL
Anko
Anko 是一个用Kotlin写的Android DSL(Domain-Specific Language),用代码实现xml的布局。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(createUI())
}
private fun createUI(): View {
// UI 需要引入anko库
return UI {
verticalLayout {
padding = dip(30)
backgroundResource = android.R.color.holo_blue_bright
var title = editText {
id = R.id.todo_title
hintResource = R.string.title_hint
}
var content = editText {
id = R.id.todo_content
hintResource = R.string.content_hint
}
button {
id = R.id.todo_add
textResource =R.string.add_todo
textColor = Color.WHITE
onClick {
if (!TextUtils.isEmpty(title.text.toString()) && !TextUtils.isEmpty(content.text.toString())) {
toast("${title.text}::${content.text}")
}
}
}
}
}.view
}
}
效果图:
Kotlin Native
Kotlin Native 主要基于LLVM(Low Level Virtual Machine)后端编译器来生成本地机器码。LLVM是构架编译器的框架系统,用C++编写而成,用于优化任意程序(用任何程序语言编写)的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。