/************************Kotlin语法总结************************/
1、?//声明为可空类型 ?=null
var ageString : String ?=null
ageString =student ? .name// ? student 为空就返回null ,不是空 就返回 对应的值
2、s?.length 就相当于 if(s!=null) s.length else null
3、!!. 属性不为空判断,为空会抛异常
4、var: var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量
val: val是一个只读变量,这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化,因为以后不能被改变
定义常量 一般用 const val 如:const val BASE_URL = "http://baobab.kaiyanapp.com/api/"
注意:const 只允许在top-level级别和object中声明
5、懒加载,只有用到时才会实例化
lateinit 只用于变量 var,而 lazy 只用于只读变量val
lateinit 则用于只能生命周期流程中进行获取或者初始化的变量,比如 Android 的 onCreate()
lateinit var name:String
该修饰只能用于类体中(不是在主构造函数中)声明的var属性,注意是var(可变属性)并且仅当该属性没有自定义getter或setter时,
该属性必须是非空类型,并且不能是原生类型
lateinit应用场景:声明属性时,还不初始化,放到一些特定时机才去初始化(如 oncreate()中初始化),并且该属性一定会赋值, private lateinit var name:String
不然,就可以采用
private var name:String?=null
val nameB: String by lazy {
println("getLazy")
"123"
}
println(nameB)
println(nameB)
输入结果:
getLazy
123
123
当属性用到的时候才会初始化”lazy{}”里面的内容
而且再次调用属性的时候,只会得到结果,而不会再次执行lazy{}的运行过程
6、:: 引用一个方法(调用方法:分为调用奔类方法this:: 调用其他类方法 a:;) 如:Intent(activity, SearchActivity::class.java)
7、 a ?: b (不为空执行a ,为空执行b)
8、 mList.filter {
it->
it.type=="banner2"||it.type=="horizontalScrollCard"
}.forEach {
it->
newBannerItemList.remove(it)
}
代替
for(item in mList){
if(it.type=="banner2"||it.type=="horizontalScrollCard"){
newBannerItemList.remove(item)
}
}
9、let 1、当你需要去定义一个变量在一个特定的作用域范围内,let函数的是一个不错的选择;2、let函数另一个作用就是可以避免写一些判断null的操作
情景一:object.let{
it.todo()//在函数体内使用it替代object对象去访问其公有的属性和方法
...
}
情景二:
object ?.let {
do(it)
} 不为空,执行do 也是空判断的一种方式
举例:
使用let前:
mVideoPlayer?.setVideoView(activity.course_video_view)
mVideoPlayer?.setControllerView(activity.course_video_controller_view)
mVideoPlayer?.setCurtainView(activity.course_video_curtain_view)
使用let后:
mVideoPlayer?.let{
it.setVideoView(activity.course_video_view)
it.setControllerView(activity.course_video_controller_view)
it.setCurtainView(activity.course_video_curtain_view)
}
10、also函数的结构实际上和let很像唯一的区别就是返回值的不一样,let是以闭包的形式返回,返回函数体内最后一行的值,
如果最后一行为空就返回一个Unit类型的默认值。而also函数返回的则是传入对象的本身
11.with(参数)
将对象作为函数的参数,在函数内可以通过 this指代该对象。
返回值为函数的最后一行或return表达式
with函数中的参数是一个对象,我们可以带方法中直接引用对象的公有属性或者公有方法,而不用使用方法名。
如果一段代码你需要多次使用一个对象,那么你就可以使用with函数
12、run
(1)、作用域 :可以拥有一个单独的区域,在这个作用域内,mood 在打印之前被重新定义成了 I am happy
fun test() {
var mood = "I am sad"
run {
val mood = "I am happy"
println(mood) // I am happy
}
println(mood) // I am sad
}
(2)、有返回值
run {
if (firstTimeView) introView else normalView
}.show()
(3)、扩展函数
webview.settings.run {
javaScriptEnabled = true
databaseEnabled = true
}
等同于
with(webview.settings) {
javaScriptEnabled = true
databaseEnabled = true
}
13、apply函数的适用场景(调用对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象)
整体作用功能和run函数很像
重要不同点:唯一不同点就是它返回的值是对象本身,而run函数是一个闭包形式返回,返回的是最后一行的值。
apply一般用于一个对象实例初始化的时候,需要对对象中的属性进行赋值。
或者动态inflate出一个XML的View的时候需要给View绑定数据也会用到
场景举例:
java:
mSheetDialogView = View.inflate(activity, R.layout.biz_exam_plan_layout_sheet_inner, null)
mSheetDialogView.course_comment_tv_label.paint.isFakeBoldText = true
mSheetDialogView.course_comment_tv_score.paint.isFakeBoldText = true
kotlin:
mSheetDialogView = View.inflate(activity, R.layout.biz_exam_plan_layout_sheet_inner, null).apply{
course_comment_tv_label.paint.isFakeBoldText = true
course_comment_tv_score.paint.isFakeBoldText = true
}
/**************let、with、run、apply、also函数总结**************/
1、apply和run 函数功能类似,区别在于apply返回的值是对象本身,run返回的是最后一行的值
2、also和let 函数功能类似,区别在于also返回的值是对象本身,let返回的是最后一行的值
14、open 被open修饰的类,才可以被继承
15、类初始化:kotlin增加了一个新的关键字init用来处理类的初始化问题,
init模块中的内容可以直接使用构造函数的参数
16、lambda表达式,只支持单抽象方法模型,也就是说设计的接口里面只有一个抽象的方法,才符合lambda表达式的规则,多个回调方法不支持
mView.setEventListener(new ExamPlanHomeEventListener(){
public void onSuccess(Data data){
//todo
}
});
mView.setEventListener({
data: Data ->
//todo
})
17、kotlin中没有switch,when相当于java中的switch
18、intArrayOf 创建一个int数组
19、位运算符
shl —— 类似Java的<<
shr —— 类似Java的>>
ushr —— 类似Java的>>>
and —— 类似Java的&
or —— 类似Java的|
xor —— 同Java中的按位异或 ^
inv —— Java中的按位取反 -
20、companion object
Kotlin语言中使用"object"修饰静态类
Kotlin语言中使用"companion object"修饰静态方法
举例:
companion object {
fun getInstance(title: String): HomeFragment {
val fragment = HomeFragment()
val bundle = Bundle()
fragment.arguments = bundle
fragment.mTitle = title
return fragment
}
fun getName(str :String):String{
return str
}
}
类中的静态方法,都写在companion object{}函数体中
21、双冒号 ::
// 调用d对象的方法getResult
d::getResult
单冒号 : 继承或实现,相当于java中的extends和implements
22、遍历
(1)、正序遍历
for (index in 1..100){
print(index)
}
(2)、反序遍历
for (index in 100 downTo 1){
print(index)
}
(3)、想不使用1作为遍历的步长,可以使用step()函数:
for (index in 1..100 step 2){
print(index)//会输出1..3..5......
}
(4)、要创建一个不包含末尾元素的区间:
for(index in 1 until 10){
println(index)//输出0..9
}
(5)、遍历一个数组/列表,想同时取出下标和元素
val array = arrayOf("a", "b", "c")
for ((index,e) in array.withIndex()){
println("下标=$index----元素=$e")
}
(6)、遍历一个数组/列表,只取出下标
val array = arrayOf("a", "b", "c")
for (index in array.indices){
println("index=$index")//输出0,1,2
}
(7)、遍历取元素:
val array = arrayOf("a", "b", "c")
for (element in array){
println("element=$element")//输出a,b,c
}
22、kotlin 中的setOnListener
采用object:OnTabSelectListener
tab_layout.setOnTabSelectListener(object : OnTabSelectListener {
override fun onTabSelect(position: Int) {
}
override fun onTabReselect(position: Int) {
}
})
23、data class相当于java中的javaBean
在申明一个 data class 有一些需要注意的事项。
主构造函数必须要至少有一个参数
主构造函数中的所有参数必须被标记为val或者var
数据类不能有以下修饰符:abstract,inner,open,sealed
data class只能实现接口(Kotlin1.1以前的规则),现在也可以继承其它类
data class User (var id:Int,var name:String)
24、过滤集合中的元素
bannerItemList.filter { item ->
item.type=="banner2"|| item.type=="horizontalScrollCard"
}.forEach{ item ->
//移除 item
bannerItemList.remove(item)
}
25、constructor
一、 Primary Constructor:
class Person constructor(username: String, age: Int){
private val username: String
private var age: Int
init{
this.username = username
this.age = age
}
}
(1)、关键字init:init{}它被称作是初始化代码块(Initializer Block),它的作用是为了Primary Constructor服务的,
由于Primary Constructor是放置在类的首部,是不能包含任何初始化执行语句的,这是语法规定的,
那么这个时候就有了init的用武之地,我们可以把初始化执行语句放置在此处,为属性进行赋值
(2)、当constructor关键字没有注解和可见性修饰符作用于它时,constructor关键字可以省略
class User{
private val username: String
private var age: Int
constructor(username: String, age: Int){
this.username = username
this.age = age
}
}
二、 Secondary Constructor
class User{
private val username: String
private var age: Int
constructor(username: String, age: Int){
this.username = username
this.age = age
}
}
和Primary Constructor相比,很明显的一点,Secondary Constructor是定义在类体中。第二,Secondary Constructor可以有多个,
而Primary Constructor只会有一个
26、digest[i] and 0xff 会报错
因为kotlin位运算只针对int类型和long类型
需要改成
digest[i].toInt() and 0xff
27、kotlin中的根据空格切割
val arr: Array<String>
arr = string.split(" +".toRegex()).toTypedArray()
28、 Cast
Java: if(a instanceof String)
Kotlin:if (a is String)
29、For
Java:
for (int i = 1; i < 11 ; i++) { }
for (int i = 1; i < 11 ; i+=2) { }
for (String item : collection) { }
for (Map.Entry<String, String> entry: map.entrySet()) { }
Kotlin:
for (i in 1..10) { }
for (i in 1..10 step 2) {}
for (item in collection) {}
for ((index, item) in collection.withIndex()) {}
for ((key, value) in map) {}
30、Inner Class
Java:
public class Documment {
class InnerClass {
}
}
Kotlin:
class Document {
internal inner class InnerClass
}
31、Nested Class
Java::
public class Documment {
public static class InnerClass {
}
}
Kotlin:
class Document {
class InnerClass
}