kotlin(运算符重载和其他约定)
在java中,有一些特定的类与语言特性相关联,例如使用了iterable接口的对象可以在for循环中使用。 而在kotlin中,也有很多与语言特性相关的函数命名,对,他与java并不一样,他是选择了将功能和函数命名来绑定。例如,如果在你的类中定义了一个名为 plus 的特殊方法,那么按照约定,就可以在该类的实例上使用+运算符。因此,在 Kotlin 中,我们把这种技术称为约定 约定因为他并不是强依赖于类和他的继承关系。在kotlin中使用约定可以在类中重载其方法,也可以通过扩展函数去添加约定,从而适应现有的java类而不用修改其代码。 运算符重载运算符重载所需要的关键词是operator,而且他所重载的方法都有特定的命名,都必须带上operator关键字。这些表达式同样也满足+-/的基本运算规则。* 表达式 函数名 a * b times a + b plus a - b minus a / b div a % b mod a * = b timesAssign a + =...
使用socket实现一个小型的聊天程序
最近在学习使用kotlin,然后试了试用socket实现一个聊天通信功能。然后发现其实kotlin用的很多库都是JAVA中已经存在的。所以更好的使用kotlin不仅要明白kotlin相对于java的优秀特性和他的跨平台能力,还需要对java也有深度的理解。 使用的插件和包:在build.gradle.kts配置文件中配置你所需要的插件和依赖。 插件 12345678910111213141516plugins { ··· id("com.github.johnrengelman.shadow") version "8.1.1" ···}tasks.withType<ShadowJar> { archiveBaseName.set("myapp") // jar 文件的基本名字 archiveVersion.set("1.0.0") // jar 文件的版本号 archiveClassifier.set("") // jar...
通过文件读写实现聊天对话(kotlin)
首先声明,这个任务并没有实现,我暂时没找到可以用来解决kotlin中实时监听键盘动作,并且不会阻塞的回调方法。 123456789101112131415161718import kotlinx.coroutines.*import java.io.Fileimport java.io.FileReader fun main()= runBlocking{ val file = File("src/main/resources/a.txt") var i = 0 while (true){ println("第${i++}次访问文件") delay(2000) println(file.readText()) println("读取完成")// if(readln()=="chat"){// var message = readln()//...
kotlin(集合和数组)
持有可空类型元素和持有非空类型元素的集合变量自己类型的可空性和用作类型参数 类型...
Kotlin(基本数据类型)
基本数据类型相比于java而言,kotlin不会区分基本数据类型和他们的包装类,都是统一的数据类型,但是他们的底层实现会和java相关。 java中Int,Boolean之类的基本数据类型都和引用类做了区分,基本数组存值,而包装类存储包含该对象的内存地址的引用。 kotlin中他不区分,都是用一个类Int,Boolean等。这样就很方便我们的操作。但是这并不意味着kotlin直接把所有的类都直接写出引用类型了。因为那样的话,就会非常低效。在运行时,数字类型尽可能的使用最高效的方式存储,大部分情况下—-对于变量,属性,参数和返回类型,kotlin的int类型都会编译为java中的基本数据类型。唯一不可行的就是泛型类,集合。他一定会编译为包装类。 可空数据类型...
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...