1 如何巧用Kotlin内置函数?
1.1 let、also、with、run、和apply区别?
1.2 until、step、downTo、in 等关键字
1.2 使用示例区别?
1.2.1 let
private fun higherFunCompare() {
val people : People = People("chen", 1, listOf("x", "y"))
/**
* let
* 作用:1.避免写判空的处理;2.使用it替代object对象在其作用域内访问属性&方法;3.返回值是最后一行 == return ...
*/
val let = people?.let {
it.age
it.name
it.isYong()
it.isMen()
999
}
LogUtils.d(TAG, "people?.let:$let")
// people?.let:999
// java
if (people != null) {
people.age
people.name
people.isYong()
people.isMen()
999
}
}
1.2.2 also
private fun higherFunCompare() {
/**
* also:类似let函数,但区别在于返回值:
* 3.返回值是传入的对象的本身
*/
val also = people?.also {
it.age
it.name
it.isYong()
it.isMen()
999
}
LogUtils.d(TAG, "people?.also:$also")
// people?.also:com.read.kotlinlib.model.People@1f24758d
}
1.2.3 with
private fun higherFunCompare() {
/**
* with:
* 1.调用同一个对象的多个方法/属性时,省去重复的对象名,直接调用方法名/属性即可;2.返回值是最后一行
*/
val with = with(people) {
LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
999
}
LogUtils.d(TAG, "with(people):$with")
// my name is chen, I am 1 years old, false, true
// with(people):999
// java
LogUtils.d(TAG,"my name is $people.name, I am $people.age years old, ${people.isYong()}, ${people.isMen()}")
}
1.2.4 run
private fun higherFunCompare() {
/**
* run:结合了let、with两个函数的作用
* 作用:1.避免写判空的处理;2.使用it替代object对象在其作用域内访问属性&方法;3.返回值是最后一行;
* 4.调用同一个对象的多个方法/属性时,省去重复的对象名,直接调用方法名/属性即可
*/
val run = people?.run {
LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
999
}
LogUtils.d(TAG, "people?.run:$run")
// my name is chen, I am 1 years old, false, true
// people?.run:999
}
1.2.5 apply
private fun higherFunCompare() {
/**
* apply:与run函数类似,但区别在于返回值:
* 3.返回值是传入的对象的本身;
*/
val apply = people?.apply {
LogUtils.d(TAG,"my name is $name, I am $age years old, ${isYong()}, ${isMen()}")
999
}
LogUtils.d(TAG, "people?.apply:$apply")
// my name is chen, I am 1 years old, false, true
// people?.apply:com.read.kotlinlib.model.People@1f24758d
}
1.3 参考链接
2 函数
// 函数返回一个Int类型的值。并且接受了一个block()函数作为该函数的参数;
// 其中block()接受一个Char类型的参数,并且返回一个Int类型的值,默认值是一个返回值为1的代码块:{1}
// sumBy函数参数是一个扩展在CharSequence类型下的函数,
// 同理block()函数参数也是一个扩展在CharSequence类型下的函数,可以缩写;
fun CharSequence.sumBy(block: CharSequence.(char: Char) -> Int = { 1 }): Int {
// == CharSequence.sumBy(block: (Char) -> Int): Int {
}
// block 本身是一个函数
// 当一个函数被内联 inline 标注后,在调用它的地方,会把这个函数方法体中的所以代码移动到调用的地方,而不是通过方法间压栈进栈的方式,从而使得方法的调用栈少一层
// 应该使用 inline 的地方: 带有 lambda 参数的函数
inline fun measure(block: () -> Unit): Long {
val start = System.currentTimeMillis()
block()
return System.currentTimeMillis() - start
}
// 当不添加 inline 时,代码中,多出了一个类,增加内存的分配;
// 类是:com/read/kotlinlib/basic/CoroutineActivity$testBlock$4.INSTANCE : Lcom/read/kotlinlib/basic/CoroutineActivity$testBlock$4
inline fun measureStr(block: (str: String) -> Unit): Long { // == fun measureStr(block: (String) -> Unit): Long {
val start = System.currentTimeMillis()
block("measureStr")
return System.currentTimeMillis() - start
}
3 for循环
// 正序遍历
for (index in 0..10){
print(index) //输出012345678910
}
// 倒序遍历
for (index in 10 downTo 1){
print(index) //输出10987654321
}
// 不使用1作为遍历的步长
for (index in 0..10 step 2){
print(index) //输出0246810
}
// 一个不包含末尾元素的区间:
for (index in 0 until 10){
print(index) //输出0123456789
}
// 遍历一个数组/列表,想同时取出下标和元素:
val arrays = arrayOf("a", "b", "c")
for ((index,e) in arrays.withIndex()){
print("下标=$index--元素=$e") //输出下标=0--元素=a 下标=1--元素=b 下标=2--元素=c
}
// 遍历一个数组/列表,只取出下标:
for (index in arrays.indices){
print("index=$index") //输出index=0 index=1 index=2
}
// 遍历取元素:
for (element in arrays){
print("element=$element") //输出element=a element=b element=c
}
4 变量
4.1 const val 和val修饰对象的主要区别
const val 可见性为public final static,可以直接访问。
val 可见性为private final static,并且val 会生成方法getNormalObject(),通过方法调用访问。
4 单例最佳写法
class SingletonDemo private constructor() {
companion object {
val instance: SingletonDemo by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
SingletonDemo() }
}
}
class SingletonDemo private constructor() {
companion object {
val instance = SingletonHolder.holder
}
private object SingletonHolder {
val holder= SingletonDemo()
}
}
companion object {
@Volatile
private var instance: DiscoveryRepository? = null
fun getInstance() = run {
instance ?: synchronized(this) {
instance ?: DiscoveryRepository().also { instance = it }
}
}
}
5 Java中调用Kotlin会遇到的坑?
5.1 @JvmField
var mWaitingDialog: WaitingDialog? = null
@JvmField
var mWaitingDialog: WaitingDialog? = null
@JvmField 将Kotlin属性作为字段暴露,使用@JvmField注解对其标注。该字段将具有与底层属性相同的可见性。否则,通过getMWaitingDialog(),kotlin会默认生成get\set方法