kotlin 疑问和理解
apply also run let 区别用法
var str :StringBuilder= StringBuilder();
var str1 = str.apply {
append("aaaaa")
22222
}
println(str1)
var str2= str.also {
it.append("xxxxx")
111
}
println(str2)
var str3= str.run {
append("xxxxx")
// 返回任何对象
111
}
println(str3)
var str4= str.let {
it.append("xxxxx")
// 返回任何对象
111
}
println(str4)
/**
* 能够优化 ViewHolder itemView
* 不重复写 ViewHolder.aaa ViewHolder.bbbb
* 删除 .layout中的id 可以及时联动
* BindView 只要存在一个就只有报错的时候才知道.
* 但是我想说的是 databind 真香
*/
饿汉式的单例
/**
* 饿汉式 在什么时候初始化?
* 启动app? 还是在实例化的时候? 不懂得你 就需要思考
* https://zhuanlan.zhihu.com/p/27142516
* https://droidyue.com/blog/2017/07/17/singleton-in-kotlin/
*/
object SimpleSingle {
fun test() {}
}
fun main() {
SimpleSingle.test()
}
java -> swtich vs kotlin when
/**
*
* swtich
* 只能指定明确的 case Value 值。
* 如果有一个 区间 不行
* 如果有一个函数式 也不行
* 。。。。
*
* 可以
* 1. 组的形式
* 2. 函数式
* 等等等
*
*/
var count: Any? = 1;
var str: String = when (count) {
is Int -> {
"1111"
}
1, 2 -> {
"111"
}
null -> {
"222"
}
add(1, 2) -> {
"111"
}
else -> ""
}
}
fun add(a: Int, b: Int): Int {
return 1;
}
delegates
https://kotlinlang.org/docs/reference/delegated-properties.html#standard-delegates
(网络上面基本上是官网的翻译,如果加一点应用场景 更好下饭)
interface MessageService {
fun processMessage(message: String): String
}
class MessageServiceImpl : MessageService {
override fun processMessage(message: String): String {
return "MessageServiceImpl: $message"
}
}
interface UserService {
fun processUser(userId: String): String
}
class UserServiceImpl : UserService {
override fun processUser(userId: String): String {
return "UserServiceImpl: $userId"
}
}
class CompositeService : UserService by UserServiceImpl(), MessageService by MessageServiceImpl() {
}
var compositeService = CompositeService()
println(compositeService.processMessage("111"))
- 委托属性
应用场景 一
```kotlin
val viewModel: ItemVM by activityScope<ItemVM>()
val title: String by lazyExtra("title", "")
val id: Int by lazyExtra("id", 0)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
private fun <T> Activity.lazyExtra(name: String, defaultValue: T): Lazy<T> {
return lazy {
when (defaultValue) {
is String -> intent.getStringExtra(name) as T ?: defaultValue
is Int -> intent.getIntExtra(name, defaultValue) as T
is Boolean -> intent.getBooleanExtra(name, defaultValue) as T
else -> throw RuntimeException()
}
}
}
private inline fun <reified VM : ViewModel> FragmentActivity.activityScope() = mainThreadLazy {
ViewModelProviders.of(this).get(VM::class.java)
}
应用场景 二
class DatabaseDelegate<in R, T>(private val field: String, private val id: Int) : ReadWriteProperty<R, T> {
override fun getValue(thisRef: R, property: KProperty<*>): T =
queryForValue(field, id) as T
override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
update(field, id, value)
}
}
/**
* 类比 sql 查询.
*/
fun main(){
var name: String by DatabaseDelegate(
"name",
1)
name="111";
println(name)
}
class DatabaseUser() {
/**
* name 变化 可以查询 数据库.
*/
var name: String by DatabaseDelegate(
"name",
1)
}
// var name: String by DatabaseDelegate(
// "SELECT name FROM users WHERE userId = :id",
// "UPDATE users SET name = :value WHERE userId = :id",
// userId)
// var email: String by DatabaseDelegate(
// "SELECT email FROM users WHERE userId = :id",
// "UPDATE users SET email = :value WHERE userId = :id",
// userId)
//}
val var lazy lateinit 区别
/**
* 同步锁
*/
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
/**
* val var
*
* var类似于一般变量,在kotlin中被称为可变变量,可以多次分配。
val类似于Final变量,在kotlin中被称为不可变的,并且只能一次初始化
* lateinit
* 可以被多次修改
* 不能被用来修饰可空的属性和java的基本类型(因为对于可空类型,会有默认值null)
* by lazy
* 线程安全
* 只拥有唯一一个声明在{}中的初始化构造器,如果你想要修改它,你只能通过在子类中覆写的方式来修改它的值。
*/
class LazySimple {
lateinit var itemValue:String ;
/**
* final
*/
val itemValue1:String = "111";
/**
* 普通变量
*/
var itemValue2:String = "2222";
val xxx:String by lazy {
"aaa"
}
}
fun main() {
lateinit var itemValue2:String ;
print(itemValue2) // error
val aaa:String by lazy {
"aaa"
}
for (i in 0..100) {
run {
System.out.println("toManyLambdaCalls currentCount=$i")
}
}
var simple= LazySimple()
simple.itemValue="1"
simple.itemValue="2"
println(lazyValue)
println(lazyValue)
}
inline
问一个问题:
调用函数 和 直接展开写 谁效率更高一点?
fun brighten(pixel: Int): Int {
return pixel + 1
}
// 黑白
fun gray(pixel: Int): Int {
return pixel + 2
}
// 方式一
fun filter001(img: Int) {
val length: Int = img
var pixel = 1;
for (i in 0 until length) {
//提高亮度
pixel = brighten(pixel)
//黑白处理
pixel = gray(pixel)
}
}
var start=System.currentTimeMillis()
for (m in 1..100000000) {
filter001(100000)
}
println("aaa "+(System.currentTimeMillis() -start)) //aaa 47
// 方式二
inline fun filter001(img: Int) {
val length: Int = img
var pixel = 1;
for (i in 0 until length) {
//提高亮度
pixel = brighten(pixel)
//黑白处理
pixel = gray(pixel)
}
}
var start=System.currentTimeMillis()
for (m in 1..100000000) {
filter001(100000)
}
println("aaa "+(System.currentTimeMillis() -start)) //aaa 6
扩展方法:
fun main (){
println("<>".escapeForxml())
println( "我要".concatAsString("xxix"))
println( 1 toPowerOf 3 )
}
fun String.escapeForxml():String{
return this
.replace("&", "1")
.replace("<", "2")
.replace(">", "3")
}
疑问:
下面形式 findViewbyId 几次?
databind.itemView…text= “1111”;
databind.itemView.visibility=View.Gone
参考:
inline (推荐阅读)
https://ybq.me/kotlin%E4%B8%AD%E7%9A%84inline/
kotlin 一些扩展
https://github.com/LouisCAD/Splitties
专业
https://www.baeldung.com/