kotlin 练习

kotlin基础语法

96 
samychen 
2017.05.28 17:07* 字数 1224 阅读 2434评论 0

每种编程语言都有必定的语法、语义和执行顺序(同步),学习一种新语言也都是从这三者出发,下面咱们就只针对kotlin的语法来作简单的介绍。javascript

Kotlin有本身的特性不应被Java的思惟所束缚。php

  1. 基本语法准则:
    在Kotlin中常量用 val 声明,变量用 var 声明;
    关键字在前面,类型以冒号 :隔开在后面,也能够省略直接赋值;
    类型后带问号 ? 表示可为空类型(默认空类型安全);
    常量 val 延迟加载 by lazy{} ;
    默认是线程安全的,关闭线程安全 lazy(LazyThreadSafetyMode.NONE){} ;
    变量 var 延迟加载 lateinit ;
    内部类和参数默认为public,而在Java中为private
    类默认为不可继承(final),想要可被继承要声明为 open 或 abstract
    取消了static关键字,静态方法和参数统一写在 companion object 块
    internal模块内可见,inner内部类
//常量数组int[][][] arrs = new int[3][2][1]; val arrs = Array(3) { Array(2) { IntArray(1) } } internal var name: String? = null//类型后带问号 ? 表示可为空类型(默认空安全) internal var age: Int = 0//internal模块内可见,inner内部类 //当咱们只有单个构造器时,咱们须要在从父类继承下来的构造器中指定须要的参数。这是用来替换Java中的super调用的。 open class Animal(name: String) class Person(name: String, surname: String) : Animal(name) 

kotlin是空类型安全的,全部变量默认为"not null",必须显式在类型后添加?修饰符才可赋值为null。html

var notNullArtist: Artist = null//编译不经过,由于notNullArtist不能为null var artist: Artist? = null//编译经过 artist.print()//编译不经过,由于artist可能为空 /** Kotlin进行空判断处理,有两种处理方式: * 1. 抛出空异常,字段后加 !! * 2. 不作处理直接跳过,字段后加 ? */ artist?.print()//编译经过,作了非空判断,只有当artist!=null时才调用print() artist!!.print()//这种用法只有在确认artist不为null时才能调用,不然抛出空指针异常 val name = artist?.name?:"empty"//当artist为null时能够指定一个默认值 
  1. 条件语句
    if...else 正常使用,不过移除了 switch 用更强大的 when 替代,when子式能够是各类返回Boolean的表达式
val x = 7
when (x) {
  in 1..5 -> print("x is in the range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") else -> print("none of the above") } 

kotlin尽量多的使用whenjava

  1. 循环语句
    while 和 do...while 同Java并没有区别, for 则有很大改变并多出了几个变种
fun main(args: Array<String>) { var list = ArrayList<String>() add(list) list.forEachIndexed { i, s -> print(list[i]) print(s) } println() //若是没有指定函数的返回值,它就会返回Unit,与Java中的void相似,可是Unit是一个真正的对象。固然也能够指定任何其它的返回类型: list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) } //递增for (int i = 0; i < list.size(); i++) for (i in list.indices) { print(list[i]) } //递增for (int i = 2; i < list.size(); i++) for (i in 2..list.size-1) { print(list[i]) } //递减for (int i = list.size(); i >= 0; i--) for (i in list.size downTo 0) { print(list[i]) } //操做列表内的对象 for (item in list) { print(item) } //增强版 for((i,item) in list.withIndex()){ print(list[i]) print(item) } //变种版 list.forEach { print(it) } list.forEachIndexed { i, s -> print(list[i]) print(s) } list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) fun add(list:MutableList<String>) { for (i in 0..4) { list.add(i.toString() + "") } } 

冒号使用
  在Kotlin中冒号 : 用万能来称呼毫不为过。常量变量的类型声明,函数的返回值,类的继承都须要它android

除此以外还有一个特别的地方也须要它,使用Java类的时候。Kotlin最终会仍是编译成Java字节码,使用到Java类是必然的,在Kotlin语法以下
val intent = Intent(this, MainActivity::class.java)git

指定上下文的@编程

除了冒号另外一个重要符号 @ ,java代码中常常用到内部类和匿名内部类,有时咱们不能肯定this指代的上下文,Java可使用XXX.this指代具体上下文,在kotlin中的作法是this@XXX数组

class User { inner class State{ fun getUser(): User{ //返回User return this@User } fun getState(): State{ //返回State return this@State } } } 

kotlin的特点

Java的 getter/setter 方法自动转换成属性,对应到Kotlin属性的调用安全

public class User { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } 

对应的kotlinbash

val user = User()
//赋值 user.name = "tutu" user.age = "23" //取值 val name = user.name val age = user.age class User { var name: String? = null var age: String? = null } 

有时 getter/setter 方法比较复杂,这就须要自定义 getter/setter 了,实现一个Java中经常使用的单例,这里只为了展现,单例在Kotlin有更简单的方法实现,只要在 package 级别建立一个 object 便可

class User { companion object {//静态方法和参数统一写在 companion object 块 //volatile不保证原子操做,因此,很容易读到脏数据。在两个或者更多的线程访问的成员变量上使用volatile @Volatile var instance: User? = null get() { if (field == null) { synchronized(User::class.java) { if (field == null) field = User() } } return field } } var name: String? = null var age: String? = null } 

自定义 getter/setter 重点在 field ,跟咱们熟悉所Java的 this 指代当前类同样, field 指代当前参数,直接使用参数名 instance 代替不会报错但单例就没效果了

字符串问题

在Java中拼接字符串的代码可读性都不好,在Kotlin字符串拼接变得很是简洁,只需用 $ 后面加上参数名,复杂的参数要加上 {}

val pair = Pair(1, "one") val (num, name) = pair println("num = $num, name = $name") 

输出num = 1, name = one

Java8新特性lambda的支持

lambda须要一个函数,可是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。使用功能接口,把接口名、方法名和参数类型省掉不写再加个 -> 罢了。

使用Java开发Android时,处理监听回调是常见的事,kotlin能够直接编写监听回调而不用再经过匿名对象传递onClick方法,这个特性被称为Lambda表达式

view.setOnclickListener({
      Toast.makeText(this, "Hello World!", Toast.LENGTH_LONG).show() }) 

扩展函数

能够为任何已经存在的类添加新函数,相比传统工具类,扩展函数更具备可读性。

//为Fragment添加扩展函数 fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGTH_LONG){ Toast.makeText(getActivity(), message, duration).show() } 

调用时直接调用fragment.toast("Hello World!")或fragment.toast("Hello World!", 2000)

Kotlin中的参数与Java中有些不一样。如你所见,咱们先写参数的名字再写它的类型。上面调用的第二个参数(length)指定了一个默认值。这意味着你调用的时候能够传入第二个值或者不传,这样能够避免你须要的重载函数。

函数式支持(lambda),函数是一级公民

集合操做

  list转map(associateBy)

  场景:订单列表转换成以 id为key 的订单map

val mainOrders = orderDao!!.queryUserOrder(param)
val orderMap = mainOrders.associateBy { it.id }.toMap()

  map的key或者value转换

  假如一个map的key是String,须要转换成Long;或者map的value是一个对象,要转成另外一个对象。按照标准Java写法,能够要new一个新的map,而后循环老的map,在kotlin中,一行代码搞定

val map = mutableMapOf(1 to 1, 2 to 2)
val newMap = map.mapKeys { "key_${it.key}" }.mapValues { "value_${it.value}" } println(newMap) //打印结果 {key_1=value_1, key_2=value_2} val pair = Pair("ss","sg") val map = mapOf(pair) val map1=map.mapKeys { entry -> "${entry.value}!" } for((key,value) in map1){ println("map1:key=$key") println("map1:value=$value") } val map2 =map.mapKeys { (key, value) -> "$value" } for((key,value) in map2){ println("map2:key=$key") println("map2:value=$value") } val map3=map.mapValues { entry -> "${entry.value}!" } for((key,value) in map3){ println("map3:key=$key") println("map3:value=$value") } val map4=map.mapValues { (key, value) -> "$value" } for((key,value) in map4){ println("map4:key=$key") println("map4:value=$value") } 打印结果: map1:key=sg! map1:value=sg map2:key=sg map2:value=sg map3:key=ss map3:value=sg! map4:key=ss map4:value=sg 

参考文献
  Kotlin for android Developers
  kotlin 脚本练习

相关文章
相关标签/搜索