当前位置: 首页 > 编程日记 > 正文

kotlin 练习

kotlin基础语法

96
samychen 
2017.05.28 17:07* 字数 1224 阅读 2434评论 0

每种编程语言都有一定的语法、语义和执行顺序(同步),学习一种新语言也都是从这三者出发,下面我们就只针对kotlin的语法来做简单的介绍。

Kotlin有自己的特性不该被Java的思维所束缚。

  1. 基本语法准则:
    在Kotlin中常量用 val 声明,变量用 var 声明;
    关键字在前面,类型以冒号 :隔开在后面,也可以省略直接赋值;
    类型后带问号 ? 表示可为空类型(默认空类型安全);
    常量 val 延迟加载 by lazy{} ;
    默认是线程安全的,关闭线程安全 lazy(LazyThreadSafetyMode.NONE){} ;
    变量 var 延迟加载 lateinit ;
    内部类和参数默认为public,而在Java中为private
    类默认为不可继承(final),想要可被继承要声明为 open 或 abstract
    取消了static关键字,静态方法和参数统一写在 companion object 块
    internal模块内可见,inner内部类
//常量数组int[][][] arrs = new int[3][2][1];
val arrs = Array(3) { Array(2) { IntArray(1) } }
internal var name: String? = null//类型后带问号 ? 表示可为空类型(默认空安全) internal var age: Int = 0//internal模块内可见,inner内部类 //当我们只有单个构造器时,我们需要在从父类继承下来的构造器中指定需要的参数。这是用来替换Java中的super调用的。 open class Animal(name: String) class Person(name: String, surname: String) : Animal(name) 

kotlin是空类型安全的,所有变量默认为"not null",必须显式在类型后添加?修饰符才可赋值为null。

var notNullArtist: Artist = null//编译不通过,因为notNullArtist不能为null
var artist: Artist? = null//编译通过 artist.print()//编译不通过,因为artist可能为空 /** Kotlin进行空判断处理,有两种处理方式: * 1. 抛出空异常,字段后加 !! * 2. 不做处理直接跳过,字段后加 ? */ artist?.print()//编译通过,做了非空判断,只有当artist!=null时才调用print() artist!!.print()//这种用法只有在确认artist不为null时才能调用,否则抛出空指针异常 val name = artist?.name?:"empty"//当artist为null时可以指定一个默认值 
  1. 条件语句
    if...else 正常使用,不过移除了 switch 用更强大的 when 替代,when子式可以是各种返回Boolean的表达式
val x = 7
when (x) {in 1..5 -> print("x is in the range")in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") else -> print("none of the above") } 

kotlin尽可能多的使用when

  1. 循环语句
    while 和 do...while 同Java并无区别, for 则有很大改变并多出了几个变种
fun main(args: Array<String>) {var list = ArrayList<String>()add(list) list.forEachIndexed { i, s -> print(list[i]) print(s) } println() //如果没有指定函数的返回值,它就会返回Unit,与Java中的void类似,但是Unit是一个真正的对象。当然也可以指定任何其它的返回类型: list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) } //递增for (int i = 0; i < list.size(); i++) for (i in list.indices) { print(list[i]) } //递增for (int i = 2; i < list.size(); i++) for (i in 2..list.size-1) { print(list[i]) } //递减for (int i = list.size(); i >= 0; i--) for (i in list.size downTo 0) { print(list[i]) } //操作列表内的对象 for (item in list) { print(item) } //加强版 for((i,item) in list.withIndex()){ print(list[i]) print(item) } //变种版 list.forEach { print(it) } list.forEachIndexed { i, s -> print(list[i]) print(s) } list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) fun add(list:MutableList<String>) { for (i in 0..4) { list.add(i.toString() + "") } } 

冒号使用
  在Kotlin中冒号 : 用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它

除此之外还有一个特别的地方也需要它,使用Java类的时候。Kotlin最终会还是编译成Java字节码,使用到Java类是必然的,在Kotlin语法如下
val intent = Intent(this, MainActivity::class.java)

指定上下文的@

除了冒号另一个重要符号 @ ,java代码中经常用到内部类和匿名内部类,有时我们不能确定this指代的上下文,Java可以使用XXX.this指代具体上下文,在kotlin中的做法是this@XXX

class User {inner class State{ fun getUser(): User{ //返回User return this@User } fun getState(): State{ //返回State return this@State } } } 

kotlin的特色

Java的 getter/setter 方法自动转换成属性,对应到Kotlin属性的调用

public class User { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } 

对应的kotlin

val user = User()
//赋值
user.name = "tutu"
user.age = "23"
//取值 val name = user.name val age = user.age class User { var name: String? = null var age: String? = null } 

有时 getter/setter 方法比较复杂,这就需要自定义 getter/setter 了,实现一个Java中常用的单例,这里只为了展示,单例在Kotlin有更简单的方法实现,只要在 package 级别创建一个 object 即可

class User {companion object {//静态方法和参数统一写在 companion object 块 //volatile不保证原子操作,所以,很容易读到脏数据。在两个或者更多的线程访问的成员变量上使用volatile @Volatile var instance: User? = null get() { if (field == null) { synchronized(User::class.java) { if (field == null) field = User() } } return field } } var name: String? = null var age: String? = null } 

自定义 getter/setter 重点在 field ,跟我们熟悉所Java的 this 指代当前类一样, field 指代当前参数,直接使用参数名 instance 代替不会报错但单例就没效果了

字符串问题

在Java中拼接字符串的代码可读性都很差,在Kotlin字符串拼接变得非常简洁,只需用 $ 后面加上参数名,复杂的参数要加上 {}

 val pair = Pair(1, "one")val (num, name) = pairprintln("num = $num, name = $name")

输出num = 1, name = one

Java8新特性lambda的支持

lambda需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。使用功能接口,把接口名、方法名和参数类型省掉不写再加个 -> 罢了。

使用Java开发Android时,处理监听回调是常见的事,kotlin可以直接编写监听回调而不用再通过匿名对象传递onClick方法,这个特性被称为Lambda表达式

view.setOnclickListener({Toast.makeText(this, "Hello World!", Toast.LENGTH_LONG).show()
})

扩展函数

可以为任何已经存在的类添加新函数,相比传统工具类,扩展函数更具有可读性。

//为Fragment添加扩展函数
fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGTH_LONG){Toast.makeText(getActivity(), message, duration).show()
}

调用时直接调用fragment.toast("Hello World!")或fragment.toast("Hello World!", 2000)

Kotlin中的参数与Java中有些不同。如你所见,我们先写参数的名字再写它的类型。上面调用的第二个参数(length)指定了一个默认值。这意味着你调用的时候可以传入第二个值或者不传,这样可以避免你需要的重载函数。

函数式支持(lambda),函数是一级公民

集合操作

list转map(associateBy)

场景:订单列表转换成以 id为key 的订单map

val mainOrders = orderDao!!.queryUserOrder(param)
val orderMap = mainOrders.associateBy { it.id }.toMap()

map的key或者value转换

假如一个map的key是String,需要转换成Long;或者map的value是一个对象,要转成另一个对象。按照标准Java写法,可以要new一个新的map,然后循环老的map,在kotlin中,一行代码搞定

val map = mutableMapOf(1 to 1, 2 to 2)
val newMap = map.mapKeys { "key_${it.key}" }.mapValues { "value_${it.value}" }
println(newMap)
//打印结果 {key_1=value_1, key_2=value_2}
val pair = Pair("ss","sg") val map = mapOf(pair) val map1=map.mapKeys { entry -> "${entry.value}!" } for((key,value) in map1){ println("map1:key=$key") println("map1:value=$value") } val map2 =map.mapKeys { (key, value) -> "$value" } for((key,value) in map2){ println("map2:key=$key") println("map2:value=$value") } val map3=map.mapValues { entry -> "${entry.value}!" } for((key,value) in map3){ println("map3:key=$key") println("map3:value=$value") } val map4=map.mapValues { (key, value) -> "$value" } for((key,value) in map4){ println("map4:key=$key") println("map4:value=$value") } 打印结果: map1:key=sg! map1:value=sg map2:key=sg map2:value=sg map3:key=ss map3:value=sg! map4:key=ss map4:value=sg 

参考文献
  Kotlin for android Developers
  kotlin 脚本练习

转载于:https://www.cnblogs.com/vana/p/10201277.html

相关文章:

软件设计之 数据库设计

[按语&#xff1a;在软件设计或是动态网站开发中&#xff0c;数据库设计时很重要&#xff0c;我觉得可以说是开发工作的核心部分&#xff0c;所以学好数据库设计&#xff0c;是很重要的&#xff0c;也是大有前途的。。。]◆&#xff0e;概念首先要搞清楚容易混淆的两个概念&…

css结构思维导图

以下的图是根据css基础&#xff0c;样式&#xff0c;框模型&#xff0c;定位以及选择器这几个方面总结出来的思维导图&#xff0c;方便记忆以及查询。 转载于:https://www.cnblogs.com/yuexiuyi/p/7352516.html

C#类的修饰符

访问修饰符:public&#xff1a;访问不受限制。protected&#xff1a;访问仅限于包含类或从包含类派生的类型。只有包含该成员的类以及继承的类可以存取.Internal&#xff1a;访问仅限于当前程序集。只有当前工程可以存取.protected internal&#xff1a;访问仅限于当前程序集或…

Appium+Python 自动化测试一之:环境安装(Android篇)

目前网上有大量AppiumPython的APP自动化测试的资料&#xff0c;这里我只是记录一下自己安装的过程&#xff0c;好让自己以后忘记的时候再翻起来看看&#xff0c;快速上手&#xff0c;不想再像之前那样踩坑。 注&#xff1a;因为之前玩过Robot FrameworkSelenium2&#xff0c;所…

sql server 2005 T-SQL @@TOTAL_READ (Transact-SQL)

返回 SQL Server 自上次启动后由 SQL Server 读取&#xff08;非缓存读取&#xff09;的磁盘的数目。 Transact-SQL 语法约定 语法 TOTAL_READ 返回类型 integer 备注 若要显示包含多项 SQL Server 统计信息&#xff08;包括读写活动&#xff09;的报表&#xff0c;请运行 sp_m…

存储结构分四类:顺序存储、链接存储、索引存储 和 散列存储

存储结构分四类&#xff1a;顺序存储、链接存储、索引存储 和 散列存储。 顺序结构和链接结构适用在内存结构中。 顺序表每个单元都是按物理顺序排列的&#xff0c;如果你想访问那个单元你可以根据提供的指针等直接访问到需要的东西&#xff0c;但是链表是逻辑连续不是物理连续…

[luoguP2618] 数字工程(DP)

传送门 离线处理。。。 先线性筛一遍。 直接预处理出所有答案。 注意要用push&#xff0c;用乘法&#xff0c;常数小。 #include <cstdio> #include <cstring> #define N 1000001 #define min(x, y) ((x) < (y) ? (x) : (y))int n, cnt; int f[N], prime[N]; b…

QOS的qmtoken 1

在有拥塞的时候高层协议如TCP可能自己可以控制下拥塞&#xff0c;因此你的队列效果可能不明显了&#xff0c;这个时候TCP就是&#xff0c;网络拥塞丢包增加&#xff0c;重传增加。此时可以定义波特率修改接口带宽&#xff0c;从而从底层截掉带宽制作拥塞或使用LR&#xff0c;LR…

关于SQL的基础知识点

文章目录一 了解SQL二 检索数据三 排序检索数据四 过滤数据五 高级数据过滤六 用通配符进行过滤七 创建计算字段八 使用数据处理函数九 汇总数据十 分组数据十一、 子查询十二、 联结表十三、 创建高级联结十四 组合查询十五 插入数据十六 更新和删除数据十七 创建和操纵表十八…

DB-MySQL:MySQL 事务

ylbtech-DB-MySQL&#xff1a;MySQL 事务1.返回顶部 1、MySQL 事务 MySQL 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&#xff0c;在人员管理系统中&#xff0c;你删除一个人员&#xff0c;你即需要删除人员的基本资料&#xff0c;也要删除和该人员相关的信息…

asp.net程序性能优化的七个方面

asp.net程序性能优化的七个方面 一、数据库操作 1、用完马上关闭数据库连接 访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证&#xff0c;比较耗费服务器资 源。ASP.NET中提供了连接池&#xff08;Connection Pool&a…

如何在Windows Server 2008 Core里面添加Role~~~

SERVER CORE 中添加服务器添加AD&#xff1a;在SERVER CORE 下安装AD必须使用UNATTEND文件来进行安装以下是一个UNATTED文件的实例; DCPROMO unattend file (automatically generated by dcpromo); Usage:; dcpromo.exe /unattend:F:\LONGHORN.txt;[DCInstall]; New forest p…

关于MySQL的四种事务隔离级别!

本文实验的测试环境&#xff1a;Windows 10cmdMySQL5.6.36InnoDB 一、事务的基本要素&#xff08;ACID&#xff09; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务开始后所有操作&#xff0c;要么全部做完&#xff0c;要么全部不做&#xff0c;不可能停滞在中间环…

[PKUWC2018]随机算法

题意&#xff1a;https://loj.ac/problem/2540 给定一个图(n<20)&#xff0c;定义一个求最大独立集的随机化算法 产生一个排列&#xff0c;依次加入&#xff0c;能加入就加入 求得到最大独立集的概率 loj2540 「PKUWC 2018」随机算法 本质就是计数题 每个点有三种状态&#…

angular4 note

纪录作为新手&#xff0c;用新版angular遇到的一些细节点 1. .angular-cli.json文件 一开始没注意这个文件干啥的&#xff0c;直到我发现有个第三方js&#xff0c;我既没有在index.html里看到引用&#xff0c;也没看到在js代码里有import&#xff0c;找了好久&#xff0c;在这…

初学 Delphi 嵌入汇编[3] - 第一个 Delphi 与汇编的例子

前面知道了一个汇编的赋值指令(MOV), 再了解一个加法指令(ADD), 就可以做个例子了.譬如: ADD AX,BX; 这相当于 Delphi 中的 AX : AX BX;另外提前来个列表 - Delphi 可以用汇编管理以下寄存器:32 位寄存器: EAX EBX ECX EDX ESP EBP ESI EDI16 位寄存器: AX BX CX DX SP BP SI …

通过应用程序域AppDomain加载和卸载程序集之后,如何再返回原来的主程序域

实现目的&#xff1a;动态加载dll&#xff0c;执行完毕之后可以随时卸载掉&#xff0c;并可以替换这些dll&#xff0c;以在运行中更新dll中的类。 其实就是通过应用程序域AppDomain加载和卸载程序集。 在这方面微软有篇文章http://www.microsoft.com/china/msdn/archives/libra…

Sql语法---DDL

1.SQL的定义 结构化查询语言(Structured Query Language)简称SQL,SQL语句就是对数据库进行操作的一种语言。 2.SQL的作用 通过SQL语句我们可以方便的操作数据库中的数据、表、数据库等。 3.SQL的分类 1. DDL(Data Definition Language)数据定义语言用来定义数据库对象&#xff…

Java程序员三年的工作经验,却不如一个新人的工资高???

文章目录一、关于程序员的几个阶段第一阶段&#xff1a;三年第二阶段&#xff1a;五年第三阶段&#xff1a;十年二、关于项目经验三、关于专业技能1、基本语法2、集合3、设计模式4、多线程5、JDK源码6、框架7、数据库8、数据结构和算法分析9、Java虚拟机10、Web方面的一些问题四…

视觉稿与H5页面之间的终端适配

移动端页面开发备注&#xff1a;该篇文章使用宽为750px&#xff08;iPhone6的设备像素&#xff09;的视觉稿编写html代码&#xff1a;<!DOCTYPE html><html><head> <title></title> <meta charset"utf-8" /></head><bo…

欢迎大家批评:CSDN Blog用户体验调查

CSDN Blog自2004年7月上线以来&#xff0c;得到了各位用户的大力支持&#xff0c;已经成为大家发表专业技术文章和进行技术交流的园地。为了给各位作者和读者提供更好的服务&#xff0c;我们组织了这次用户问卷调查&#xff0c;希望大家能够将意见反馈给我们。 CSDN Blog团…

几个我收藏的经典网站

壁纸酷:[url]http://www.bizhiku.net[/url],XP壁纸,vista壁纸,汽车壁纸,风景壁纸,游戏壁纸,美女桌面壁纸,3d壁纸,日历月历壁纸等等,精美桌面壁纸下载.WAP中国:[url]http://www.wapcn.net[/url],专业的手机资源网站下载,手机铃声,手机游戏,手机壁纸,手机电影,手机软件,手机主题下…

用Java求一个三位数,该三位数是与其每位数字的阶乘之和

题目&#xff1a;一个三位数&#xff0c;该三位数与其每位数字的阶乘之和 代码&#xff1a; public class TestSum {public static void main(String[] args) {int a, b, c, i;//for循环找那个满足条件的三位数&#xff08;i&#xff09;for (i 100 ; i < 999; i) {a i %…

Storm 0.9安装指南

Storm 0.9.2安装指南0 Storm0.9的亮点引用网上的描写叙述&#xff1a;“Storm 0.9.0.1版本号的第一亮点是引入了netty transport。Storm网络传输机制实现可插拔形式&#xff0c;当前包括两种方式&#xff1a;原来的0mq传输&#xff0c;以及新的netty实现。在早期版本号中&#…

WinForm 设置初始位置在屏幕右下角

base.Location new Point(Screen.PrimaryScreen.WorkingArea.Width - base.Width, Screen.PrimaryScreen.WorkingArea.Height - base.Height);转载于:https://www.cnblogs.com/RobotTech/archive/2008/01/31/1059548.html

给博客增加了一个主题Nautica02Liquid

在Open Source Web Design上看到一个主题&#xff0c;觉得很不错&#xff0c;于是将其Adapted成BlogEngine的主题&#xff0c;费劲功夫改出来后发现效果不是很好&#xff0c;个人认为是汉字在某些精美的主题上倒是不很适应&#xff0c;没有办法…… 但是总归是做出来了&#xf…

php 基于socket的基本通信

php 基于socket的基本通信 1、前言 Socket是应用层与TCP/IP协议族通信的中间软件抽象层&#xff0c;它是一组接口。在设计模式中&#xff0c;Socket其实就是一个门面模式&#xff0c;它把复杂的TCP/IP协议族隐藏在Socket接口后面&#xff0c;对用户来说&#xff0c;一组简单的接…

SpringBoot实战(十四)之整合KafKa

本人今天上午参考了不少博文&#xff0c;发现不少博文不是特别好&#xff0c;不是因为依赖冲突问题就是因为版本问题。 于是我结合相关的博文和案例&#xff0c;自己改写了下并参考了下&#xff0c;于是就有了这篇文章。希望能够给大家帮助&#xff0c;少走一些弯路。 一、KafK…

Java 对象的生命周期

Java对象的生命周期 在Java中&#xff0c;对象的生命周期包括以下几个阶段&#xff1a; 创建阶段(Created)应用阶段(In Use)不可见阶段(Invisible)不可达阶段(Unreachable)收集阶段(Collected)终结阶段(Finalized)对象空间重分配阶段(De-allocated) 图1. JavaObject Life Cyc…

ThinkPad -- Intel 无线网卡网络连接方法限制及无法用 Fn + F5 控制的问题

[url]http://www-900.ibm.com/cn/support/tscdoc/html/JLII-6R6E5C.HTML[/url]文章编号:JLII-6R6E5CThinkPad -- Intel 无线网卡网络连接方法限制及无法用 Fn F5 控制的问题适用机型:所有ThinkPad R50; 所有ThinkPad R50e; 所有ThinkPad R50p; 所有ThinkPad R51; 所有ThinkPad…