val value: String? = "HelloWorld" val name: String = getName() ?: return //若是是null就return println("$arg1 + $arg2 = ${arg1 + arg2}") //字符串模板 val FINAL_HELLO_CHINA = "HelloChina" //类型能够不写,自动推导 val args1 = arrayOf(1,2,3) val range: IntRange = 0..1024 // [0, 1024] val range_exclusive: IntRange = 0 until 1024 // [0, 1024) = [0, 1023] class A { var b = 0 lateinit var c: String //var延迟初始化用lateinit,使用 lateinit 关键字,变量在定义时不须要初始化,因此在使用questionTextView变量时,不须要加上 ? 和 !! 操做符。在使用第一次变量以前,必定要保证为questionTextView赋值 , 否则会出现空指针异常。 lateinit var d: X val e: X by lazy { //val延迟初始化用lazy代理 println("init X") X() } //第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果, 后续调用 get() 只是返回记录的结果。 private val linearLayoutManager by lazy { LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false) } var cc: String? = null //初始化成null很差 } abstract class Person(open val age: Int) { //只有open的成员和类才能被继承,接口和抽象类默认是open的 abstract fun work() } //没有三目运算符,可使用if 表达式 val max = if (a > b) a else b //对于bean对象能够这样写 data class Forecast(val date: Date, val temperature: Float, val details: String) //Kotlin 的构造函数能够写在类头中,跟在类名后面 class Person( var name:String){ private var description: String? = null //在主构造函数中不能有任何代码实现,若是有额外的代码须要在构造方法中执行,你须要放到init代码块中执行 init { name = "Zhang Tao" } internal fun sayHello() { println("hello $name") } fun printName(){ println(name) } //这里咱们让次级构造函数调用了主构造函数,完成 name 的赋值。 // 因为次级构造函数不能直接将参数转换为字段,因此须要手动声明一个 description 字段,并为 description 字段赋值。 constructor(name: String, description: String) : this(name) { this.description = description } } class Latitude private constructor(val value: Double) { companion object {//伴随对象 //加上这个注解Java能够直接像静态那样调用,不然得Latitude.companion.ofDouble(3.0) @JvmStatic fun ofDouble(double: Double): Latitude { return Latitude(double) } fun ofLatitude(latitude: Latitude): Latitude { return Latitude(latitude.value) } @JvmField val TAG: String = "Latitude" } } class Manager : Driver, Writer { override fun write() { } override fun drive() { } } //扩展方法,不用运算符operator的话,用"abc".times(16)这样来调用,jva能够类名.times("abc", 16)调用 operator fun String.times(int: Int): String { val stringBuilder = StringBuilder() for (i in 0 until int) { stringBuilder.append(this) } return stringBuilder.toString() } //函数引用 val pdfPrinter = PdfPrinter() args.forEach(pdfPrinter::println) class PdfPrinter { fun println(any: Any) { kotlin.io.println(any) //重名了能够用包名调用 } } //常见的高阶函数 val list = listOf<Int>(1, 2, 3, 5, 10, 8, 2) val newList = ArrayList<Int>(); list.forEach { val newElement = it * 2 + 3 newList.add(newElement) } //和上面同样,上面麻烦,map能够对集合进行操做,返回一个修改过得集合 //flatmap,对集合的集合进行操做,省去了俩次遍历的麻烦 val newList2 = list.map { it * 2 + 3 } val newList3 = list.map { Int::toDouble } newList3.forEach(::println) newList3.map(::println) //和上面输出同样,可是又从新add了一个集合,很差,纯粹用于迭代的话会影响性能,实现里面还有一个数组 //提取开头指定数量或符合指定条件的子集 list.takeWhile { it <= 3 }.forEach(::println) //小于的去掉 list.forEach { if (it % 2 == 0) { println(it) } } list.filter { it.isEvent() }.forEach(::println)//过滤 val person = findPerson(); //person是可null的,因此须要? println(person?.age) println(person?.name) //上面太麻烦,findPerson加了?,因此后面不须要了,减小的判空操做。let能够安全调用 findPerson()?.let { person -> person.work() println(person.age) } //还能够更简洁,person也不用写 findPerson()?.apply { work() println(age) } //使用apply作对象的初始化 return TextView(context).apply { text = "test" setOnClickListener(onClickListener) } //use不用close了 BufferedReader(FileReader("hello.txt")).use { var line: String? while (true) { //it表示当前对象BufferedReader,因此能够用它的方法 line = it.readLine() ?: break println(line) } }
take是从集合中取前几个元素
takeLast是从集合中取后几个元素
sortedBy 排序
过滤list,符合过滤条件的就是过滤结果
filterNot把符合条件的过滤掉,剩下的是结果。这个操做和 filter 相反
slice,取集合中的某一部分java
val numbers = listOf("one", "two", "three", "four", "five", "six") println(numbers.slice(1..3)) println(numbers.slice(0..4 step 2)) println(numbers.slice(setOf(3, 5, 0))) [two, three, four] [one, three, five] [four, six, one] val numbers = listOf("one", "two", "three", "four", "five", "six") println(numbers.takeWhile { !it.startsWith('f') }) println(numbers.takeLastWhile { it != "three" }) println(numbers.dropWhile { it.length == 3 }) println(numbers.dropLastWhile { it.contains('i') }) [one, two, three] [four, five, six] [three, four, five, six] [one, two, three, four]
fun toast(message: String, length: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message, length).show() } toast("hello") //扩展函数,咱们就能够在每个Activity中直接使用toast()函数了。 fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message, duration).show() }
!! 强⾏行行调⽤用符
?. 安全调⽤用符api
/* * 不推荐这样的写法:链式的连续用!!. * */ val user = User() user!!.name!!.subSequence(0,5)!!.length
在 Kotlin 中建立单例不用像 Java 中那么复杂,只须要把 class 换成 object 就能够了。数组
object Sample { val name = "A name"} //饿汉式的单例,而且实现了线程安全 object A { val number: Int = 1 、 fun method() { println("A.method()") } }
companion 能够理解为伴随、伴生,表示修饰的对象和外部类绑定。相似静态变量
写在顶级的函数(不须要在class里写方法)或者变量有个好处:在 Android Studio 中写代码时,IDE 很容易根据你写的函数前几个字母自动联想出相应的函数。这样提升了写代码的效率,并且能够减小项目中的重复代码。
若是想写工具类的功能,直接建立文件,写 top-level「顶层」函数。安全
建立数组,增长不少有用的工具函数
contains()first()find()app
val strs: Array<String> = arrayOf("a", "b", "c")
循环经过标准函数 repeat()ide
repeat(100) { // todo }
map也能够这样建立函数
val map = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 3)
listOf() 建立不可变的 List,mutableListOf() 建立可变的 List工具
Kotlin 中集合分为两种类型:只读的和可变的。这里的只读有两层意思:
集合的 size 不可变
集合中的元素值不可变
能够转换性能
map.toMutableMap()
构造器ui
class User constructor(var name: String) { // 直接调用主构造器 constructor(name: String, id: Int) : this(name) { } // 经过上一个次构造器,间接调用主构造器 constructor(name: String, id: Int, age: Int) : this(name, id) { } }
forEach:遍历每个元素
filter:对每一个元素进行过滤操做,若是 lambda 表达式中的条件成立则留下该元素,不然剔除,最终生成新的集合
map:遍历每一个元素并执行给定表达式,最终造成新的集合
flatMap:遍历每一个元素,并为每一个元素建立新的集合,最后合并到一个集合中
Elvis 操做符
经过 ?: 的操做来简化 if null 的操做
fun validate(user: User) { val id = user.id ?: return // 验证 user.id 是否为空,为空时 return } // 等同于 fun validate(user: User) { if (user.id == null) { return } val id = user.id }
== :能够对基本数据类型以及 String 等类型进行内容比较,至关于 Java 中的 equals
=== :对引用的内存地址进行比较,至关于 Java 中的 ==
若是每一个类型都去实现诸如 TextViewList、ActivityList 这样的具体的类型,显然是不可能的。所以就诞生了「泛型」,它的意思是把具体的类型泛化,编码的时候用符号来指代类型,在使用的时候,再肯定它的类型
使用关键字 out 来支持协变,等同于 Java 中的上界通配符 ? extends。
使用关键字 in 来支持逆变,等同于 Java 中的下界通配符 ? super。
var textViews: List<out TextView> var textViews: List<in TextView>
Kotlin 标准函数
使⽤用时能够经过简单的规则做出一些判断
apply 适合对一个对象作附加操做的时候
let 适合配合空判断的时候
with 适合对同一个对象进行屡次操做的时候
协程就是kotlin官方提供的线程api
属性委托
有些常见的属性操做,咱们能够经过委托方式,让它实现,例如:lazy 延迟属性: 值只在第一次访问的时候计算
类委托
能够经过类委托来减小 extend类委托的时,编译器回优使用自身从新函数,而不是委托对象的函数
interface Base{ fun print() } case BaseImpl(var x: Int):Base{ override fun print(){ print(x) } } // Derived 的 print 实现会经过构造函数的b对象来完成class Derived(b: base): Base by b
委托就是代理
//接口代理,能够不是必须实现接口或抽象类的方法 class SeniorManager(val driver: Driver, val writer: Writer) : Driver by driver, Writer by writer class CarDriver : Driver { override fun drive() { println("开车呢") } } class PPTWriter : Writer { override fun write() { println("作PPT呢") } } interface Driver { fun drive() } interface Writer { fun write() } val driver = CarDriver() val writer = PPTWriter() val seniorManager = SeniorManager(driver, writer) seniorManager.drive() seniorManager.write() //类委托 interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() { print(x) } } class Derived(b: Base) : Base by b//实现继承的代替方式 fun main(args: Array<String>) { val b = BaseImpl(10) Derived(b).print() // prints 10 }
使用 类名::class 获取的是 Kotlin 的类型是 KClass 使用 类名::class.java 获取的是 Java 的类型 Any Kotlin 的顶层父类是 Any ,对应 Java 当中的 Object ,可是比 Object 少了 wait()/notify()等函数 Unit Kotlin 中的 Unit 对应 Java 中的 void 在 Java 中经过 「类名.this」 获取目标类引用 在 Kotlin 中经过「this@类名」获取目标类引用