kotlin(类型系统)
可空性 在java中,运行一个程序,往往遇到的最多的错误就是空指针异常,而空指针异常他是个运行时异常,往往不会指明究竟是哪一行的问题,这就让程序员非常的头疼。 而kotlin的解决方案就是把运行时错误转为编译期的错误。让程序员可以在编译时就减少错误异常的产生。通过区分可空和非空两种数据类型。 可空类型在kotlin中,所有的常见类型都是默认非空的,也就是不能接受null作为参数。除非显示的把他标记为可空,即在类型后面加上?。但是,一旦声明了是可控类型,就会有很多操作受到限制,kotlin会直接拒接一部分函数的调用,除非你对他进行了非空判断处理,然后kotlin系统就会只能判断类别,然后你才能继续执行。例如: 1fun strLen(s:String?) = if(s!=null) s.length else...
kotlin(序列)
序列引出序列的使用,首先当我们在使用集合的各种便携式API函数时,他会创建一个中间列表,最后返回。这在使用中并没有什么问题,但是如果采用了链式的多个函数操作,以及集合的基数很大时就会导致效率低下。例如这个,他会在中途生成两个列表,如果基数很大将会变得非常低效。 1people.map(Person: :name) .filter { it.startsWith ("A")} 而序列就是一种惰性集合,他一样可以使用集合所有的api方法,但是他不会在中间创造集合存储,而是类似java中的流。他是一个迭代器的形式,每个元素每个元素的遍历,然后最后在生成结果,如果没有最后的生成结果的步骤,他不会进行之前的操作。 Sequence接口惰性集合的接口就是Sequence接口,而且他只提供了一个方法,也就是iterator。因为Sequence是惰性的,所以他可以很高效的对集合元素执行链式操作,而且不会产生额外的中间集合。 序列操作序列操作有两种,一种中间操作,他返回的任然是序列,一种是末端操作,他返回的结果,可以是任何所需要的对象。中间操作始终是惰性的...
Kotlin(lambda函数)
lambdalambda表达式根据图片可以比较清晰的了解lambda的语法,他通过->将参数和函数体分开,参数不用带小括号,整体都用一个中括号括起来,箭头右边写函数体,函数体可以写多行,最后一行做为表达式的值传递回去。为了让你加深理解。 实例1:1234fun main(args: Array<String>) { //{x:Int,y:Int -> x+y}本身就是一个函数 println({x:Int,y:Int -> x+y}(1,2))} 以上内容,肯定了lambda函数表达式,他本身就是一个函数,可以直接使用。像一个正常函数一样。但是这样子意义不大,就像是刻意为之 实例2:1234fun main(args: Array<String>) { var sum = {x:Int,y:Int -> x+y} ...
kotlin(object)
Object单例模式在kotlin中,可以非常简单的通过这个关键词实现一个单例类。他可以实现接口,继承类,也可以用扩展方法去扩展类。他就是一个非常完美的类的声明方法。 当然,同理的作为一个单例类,他并没有构造方法,也就是如果你使用constructor将会直接导致报错。 如果在java中要调用kotlin中的object对象,他需要通过一个字段INSTANCE来实现,具体实例如下 12345678910111213141516//kotlinopen class Student:Child{ fun call(){ println("我会叫") }}object child1:Student(){ val name="abc"}//javapublic class Test { public static void main(String[] args) { child1.INSTANCE.walk();...
kotlin数据类和委托
数据类简单点说:使用data class关键字,声明一个数据类,该类会帮你自动重写toString(),equal(),HashCode()方法。通常来说,数据类的属性都是val的,即不可改变。因为通常创建数据类用于持续化数据维持,或者作为HashMap的一个键使用。而改变数据类的属性都会导致他本身失去意义。因此,kotlin为你提供了一个方法可以copy()本身。同时也可以修改某些属性值。 类委托使用by关键字。一个类的方法不在该类中定义,而是直接委托给另一个对象来处理。 修饰器模式这种模式的本质就是创建一个新类,实现与原始类一样的接口并将原来的类的实例作为一个字段保存。与原始类拥有同样行为的方法不用被修改,只需要直接转发到原始类的实例。简单点说就是给原始类套了一层壳,然后所有的接口的法方法直接转交给原始类去完成,只不过可以添加一些自定义的新方法,或者重写一部分的方法。如果在java中去实现,也没有问题,只是需要重复写很多的模板代码。而在kotlin中,他通过by关键字实现类委托。 123456789101112131415161718interface...
Kotlin(类,class)
初始化类 123456class User (_nickname:String){ val nickname:String init{ nickname = _nickname }} 以上就是一个kotlin类的初始化,他的主构造函数直接写在User类后面,还省略了关键字constructor。但是由于语法结构的问题,他没有函数体,所有就通过init与主构造方法一起使用。在类中的元素必须初始化,可以如上图所示,也可以直接赋值。val nickname:String = _nickname kotlin还可以化简操作,直接把属性声明在主构造函数中1class User(val...
Android(Fragment)
Fragment是什么Fragment是一种可以嵌入在Activity当中的UI片段。你可以将Fragment理解成一个迷你型的Activity,虽然这个迷你型的Activity有可能和普通的Activity是一样大的。解决某些问题:一个页面只能展示一个activity,如果要展示另一个的话,需要入栈和出栈。但是一个activity中可以包含很多个fragment。实现了多页面共存。 简单使用 首先为我们的fragment创建两个布局文件如下: 12345678910111213<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" ...
kotlin数组初始化
Array今天在leetcode刷题时,突然发现,自己不会使用最基础的数组以及他的初始化。所以在这里说明一下 使用arrayOf()这是官方推荐的一种写法,他接受的时可变长参数,也就是可以接受任意的参数,直接生成一个数组。 使用arrayOfNull<>(n),初始化一个数组全为空,接受参数为数组的大小。 直接使用Array()生成数组。他又两种构造器 直接传递一个int,这个就是他的size。 除了传递一个int外,还可以传递一个lambda函数,作为数组的初始值。
Kotlin延迟初始化和密封类,内部类
延迟初始类 这个应用的前提:很多情况下,我们会先初始化一个类,但是因为没有给他赋值,就给他赋值为null。如: 1private var adapter: MsgAdapter? = null 而在kotlin中,对于可能为空的变量,需要进行很多次非空判断,非空保护,即便你知道他不可能为空。以满足他的语法规则。 延迟初始化然后这里提供一种方法: 1private lateinit var adapter: MsgAdapter lateinit这个关键字表明当前这个变量不会立刻初始化,而是会在后面的步骤中赋值。但是他也有一个问题,如果你在使用这个变量时,没有赋值,他会抛出没有初始化的异常UninitializedPropertyAccessException。解决这个问题的方法就是在给他初始化的时候加一个判断是否初始化。 123if (!::adapter.isInitialized) { adapter = MsgAdapter(msgList) } 这是一个固定的语法规则,能判断是否完成初始化。 密封类密封类的关键字是sealed...
Android入门(RecyclerView控件)
RecyclerView控件首先,他并不是系统自带的控件,而是在androidx中的,也就是还需要从外部导入。不过好在IDEA已经帮我们导入过了,在build.gralde中 12345678910dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' testImplementation 'junit:junit:4.13.2' androidTestImplementation...