Kotlin基础入门之必知必会,查漏补缺来一手~~~
数据类型
Kotlin跟 java 相同,基本数据类型有八种 boolean,char,int,short,long,float,double,byte
类型 | 位宽 | 最小值 | 最大值 |
---|---|---|---|
Short | 16 | -32768 | 32767 |
Int | 32 | (-2^31) | (2^31-1) |
Long | 64 | (-2^63) | (2^63-1) |
Byte | 8 | -128 | 127 |
Float | 32 | - | - |
Double | 64 | - | - |
根据数据类型,结合代码看下
// 如果变量是数字,kotlin 的数据类型默认就是 Int 类型,如果超出了 Int 的取值范围,编译器就会自动推断为 Long 类型
// 根据 number 的取值范围,推断出 number 为 Int 类型
val number = 100
// 显示声明为 Int 类型
val intNumber: Int = 100
// 由于 number2 的取值范围超出 Int 的范围,编译器推断该变量升级成 long 类型
val number2 = 9999999999
// 显示声明为 long 类型
val longNumber: Long = 100L
// Kotlin 对小数的默认推断是 Double 类型(如同Java)
val number3 = 3.1415926535898
// 显示声明为 Double 类型
val doubleNumber: Double = 3.1415926535898
// 如需要声明 Float 类型,则只需在变量后面添加 F/f 即可
val number4 = 3.1415926535898f
// 显示声明为 Float 类型
// val floatNumber:Float = 3.1415926535898 // 这边编译会报错,原因如下
// 特别留意的是,kotlin 的 Float 类型十进制位数规定了6位,所以如果超出了6位,则会出现精度丢失的情况
println("number4: $number4") // 输出结果为:number4: 3.1415927
// 多说一句,Kotlin 与 Java 有一点不同的是,Kotlin 是不会像 Java 进行变量的隐形转换的,举个栗子,
// 你如果声明了 Double 变量,就只能接受 Double 类型的值,不能接收 Float 、 Int或者其他基本类型。
// 字符串类型(引用类型)
val str = "hello world"
// 显示声明为 String 类型
val strString: String = "hello world"
// 可通过下标值来取
val str1 = str[4] // 这里取出的值是 o ,并且是 char 类型
// 关于 Kotlin 的输出方式可以通过模板模式来输出,如下
println("str is $str1") // str is o
println("str length is ${str.length}") // str length is 11
// 其他类型就不一一演示了,跟上面演示的都差不多了。
Kotlin 是通过调用 to+基本类型来实现类型之间的强制转换
类型 | 强转方法 |
---|---|
Byte | toByte() |
Char | toChar() |
Short | toShort() |
Int | toInt() |
Long | toLong() |
Float | toFloat() |
Double | toDouble() |
Boolean | - |
扩展: 由于不同的表示方式,较小类型并不是较大类型的子类型,较小的类型不能隐式转换为较大的类型。 这意味着在不进行显式转换的情况下我们不能把 Byte 型值赋给一个 Int 变量。(菜鸟教程)例如:val b: Byte = 1 // OK,字面值是静态检测的 val i; Int = b // 错误 val i: Int = b.toInt() // OK
数组
数组是一种初始化时指定容器大小,不可以动态调整其大小的容器。kotlin为数组增加了一个Array类,为元素是基本类型的数组增加了IntArray、Double类等其他基本类型。
下面介绍Kotlin常用的数据创建方式
// 1.使用arrayOf创建数组,必须指定数组的元素,数组中的元素可以是任意类型
val arrayNumber = arrayOf(1, 2, 3, 4, 5)
// 显示声明 Int 类型
val arrayNumber2: Array<Int> = arrayOf(1, 2, 3, 4, 5)
// 可通过下标值来赋值
arrayNumber[4] = 6
// 不显示声明类型时,可以是任意类型
val arrayNumber3 = arrayOf(1, 2, "3", true, JSONObject())
// 也可以声明为 Any 类型,相当于 Java 的 Object
val arrayNumber4: Array<Any> = arrayOf(1, 2, "3", true, JSONObject())
// 2.使用arrayOfNulls创建一个指定大小且所有元素为空的数组,必须指定集合中的元素类型以及长度
val list = arrayOfNulls<String>(5)
list[0] = "zhangsan"
...
// 3.利用array的构造函数,动态创建数组
// 用接受数组大小以及一个方法参数的 Array 构造方法,用作参数的方法能够返回给定索引的每个元素初始值
val array = Array(10) { it -> (it * it).toString() }
// 普通的foreach方法,将数组里面的数据进行输出
array.forEach { it -> println(it) }
// foreach增强版,会依次回调给我们数组中的索引和元素值
array.forEachIndexed { index, item ->
println("$index : $item")
}
当然,Kotlin中同样也会提供专门的原生类型数组:
原生类型数组 | 解释 |
---|---|
ByteArray | 字节型数组 |
ShortArray | 短整型数组 |
IntArray | 整型数组 |
LongArray | 长整型数组 |
BooleanArray | 布尔型数组 |
CharArray | 字符型数组 |
FloatArray | 浮点型数组 |
DoubleArray | 双精度浮点型数组 |
由于原生数组跟普通的数组定义一样,具体怎么使用,就不一一展示了
扩展: 因为在Kotlin数组类型不属于集合的一种,虽然用法跟集合很相似,数组和集合之间可以互相转换,初始化集合的时候可以传入数组
集合
集合在Kotlin中应用非常广泛,例如普通的变量集,对象集,封装json类型的请求参数集合等等。集合与数组最明显的特点就是集合可以动态改变自己的长度,数组不可以。
- List:有序集合,可以通过索引下标来访问元素。允许数据重复
- Set:无序且唯一的集合,set中的元素顺序不会按照插入的顺序一样,并且不允许出现重复元素
- Map:也称字典,是一种以键值对存在的集合,键是唯一的,每个键对应着特定的值,且值允许重复
创建方式 | 范例 | 说明 | 是否可变 |
---|---|---|---|
arrayListOf() mutableListOf () | arrayListOf(1,2,3) mutableListOf() | 必须指定元素类型 | 是 |
listOf() | listOf(1,2,3) | 必须指定元素类型和初始化数据元素 | 否 |
arraySetOf() mutableSetOf () | arraySetOf(1,2,3)) mutableSetOf() | 集合内元素会自动去重 | 是 |
setOf() | setOf(1,2,3) | 必须指定元素类型,自动去重 | 否 |
arrayMapOf< K,V >() mutableListOf < K,V >() | arrayMapOf(Pair("key","value")) mutableMapOf() | 初始元素使用Pair包装 | 是 |
mapOf() | mapOf(Pair("key","value")) | 必须指定初始元素,使用Pair包装 | 否 |
mutableListOf
的常用Api如下
- example.reverse() // 集合反转(倒序输出)
- example.shuffle() // 随机排列元素(随机输出)
- example.sort() // 顺序输出(按a-z的顺序) sortDescending 则相反
方法
下面将Kotlin的方法分为下面三个模块进行讲解
- 方法声明
- 方法参数
- 方法用法
方法声明
Kotlin有三种声明方法的方式,分别为
- 普通类的方法
- 静态类的方法
- companion object 伴生类的方法
普通类的方法
class Person {
fun test() {
println("成员方法")
}
}
fun main() {
// 普通类的成员方法声明与调用
// 需要先构建实例对象,才能访问成员方法
Person().test()
}
静态类的方法
如果想要实现一个工具类的话,可以通过关键字object
来创建一个静态类
object commonUtil {
fun add(x: Int, y: Int): Int {
return x + 2
}
}
fun main() {
// 静态类里面的方法,都是属于静态方法
// 不需要构建实例对象,可以通过类名来访问静态方法
commonUtil.add()
}
companion object伴生类的方法
虽然Kotlin中没有static关键字,但是我们可以通过companion object
来实现类静态方法的目的
class Person {
fun test() {
println("成员方法")
}
companion object{
fun test2() {
println("静态方法")
}
}
}
fun main() {
// 普通类的成员方法声明与调用
// 需要先构建实例对象,才能访问成员方法
Person().test()
// 可通过类名来调用方法
Person.test()
}
方法参数
- 默认参数
- 具名参数
- 可变数量的参数
默认参数
方法中的参数可以有默认值,可以通过类型后面的=
来设置默认值
fun add(x: Int = 0, y: Int) {}
具名参数
如果一个默认参数在一个无默认值的参数之前,那么无默认值的参数,只能通过使用具名参数
来调用该方法来使用
fun add(x: Int = 0, y: Int) {}
add( y = 1) // 仅通过给 y 赋值,而 x 使用默认值 0
如果最后一个参数是方法,那么它既可以作为具名参数
在括号内传入,也可以在括号外传入
fun add(x: Int = 0, y: Int, action:() -> Unit) {}
read(y = 1){println("hello")} // 括号外传入
read(y = 1, action = {println("hello")}) // 括号内传入
可变数量的参数
方法的参数(通常是最后一个)可以用vararg
修饰符标记
fun append(vararg str: Char): String {
val result = StringBuffer()
for (char in str){
result.append(char)
}
return result.toString()
}
传递可变数量的参数
append('k','o','t','l','i','n')
if表达式
带返回值 if 表达式
在kotlin当中,由于if是一个表达式所以它会返回一个值,表达式的值为表达式作用域内最后一行的值。
fun max(a: Int, b: Int): Int {
return if ( a > b ) a else b
}
多级 if 表达式
fun eval(number: Number) {
if (number is Int) {
println("this is int number")
} else if (number is Double) {
println("this is double number")
}else if (number is Long) {
println("this is long number")
}
...
}
fun main() {
eval(100)
}
when表达式
fun eval(number: Number): String = when (number) {
is Int -> this is int number
is Double -> this is double number
is Long -> this is long number
...
}
fun main() {
eval(100)
}
循环控制
for循环
for循环可以对任何提供迭代器iterator
的对象进行遍历,写法为 for item
in elements
,最常用的应用就是迭代集合
val items = listOf("kotlin","java","python")
for (item in items) {println(item)}
除此之外,扩展一下,for循环还有两种其他遍历方式
val items = listOf("kotlin","java","python")
items.forEach {item -> println("forEach:${item}")}
items.forEachIndexed {index, item -> println("forEachIndexed:${index},${item}")}
do-while
// 当 condition 为 true时执行循环体
while(condition) {
...
}
// 循环体第一次会无条件地执行。之后,当condition为true时才执行
do {
...
} while (condition)
迭代区间和数列
for 可以循环遍历任何提供了迭代器的对象。即:有一个成员函数或者扩展函数 iterator()
,它的返回类型,有一个成员函数或者扩展函数 next()
,并且有一个成员函数或者扩展函数 hasNext()
返回Boolean
for (i in 1..10) {
// 遍历区间,kotlin的区间的包含 [1,10]
print("$i ") // 输出结果为 : 1 2 3 4 5 6 7 8 9 10
}
for (i in 1 until 10) {
// until 不包含最后一个元素,左闭右开的区间 [1,10)
print("$i ") // 输出结果为 : 1 2 3 4 5 6 7 8 9
}
for (i in 10 downTo 1 step 2) {
// 从 10 开始,每隔2个元素打印一次
print("$i ") // 输出结果为 : 10 8 6 4 2
}
break 和 continue
- break:终止最外层的循环
- continue:终止当前循环,开始下一次循环
泛型
泛型是一种语法糖,其实就是把类型参数化,它的引入给强类型编程语言加入了更强的灵活性。
好处
- 将代码通用化,可应用到多个业务模块
- 增强代码的健壮性,避免了
ClassCastException
类转换异常 - 方便造轮子,解决实际的问题
常见的泛型应用有:泛型类、泛型接口、泛型方法和泛型属性
泛型接口/泛型类(泛型类型)
定义泛型类型,是在类型名之后、主构造函数之前用尖括号括起的大写字母类型参数指定:
泛型接口
interface Person<T> {
fun study(): T
fun run(t: T)
}
class Student : Person<String> {
override fun run(t:String) {
print("run:${t}")
}
}
fun main() {
val student = Student()
student.run("跑步")
}
泛型类
abstract class Color<T>(val t: T) {
abstract fun printColor()
}
class BlueColor(val color: String) : Color<String>(color) {
override fun printColor() {
print("printColor:${color}")
}
}
fun main() {
val blueColor = BlueColor("蓝色")
}
泛型字段
定义泛型类型字段,可以完整地写明类型参数,如果编译器可以自动推定类型参数,也可以省略类型参数
abstract class Color<T>(val t: T /*泛型字段*/) {
abstract fun printColor()
}
泛型方法
fun <T> fromJson(json: String, tClass: Class<T>): T? {
val t: T? = tClass.newInstance()
return r
}
fun main() {
fromJson("{}", String::class.java)
}
至此,Kotlin的入门教程就告一段落了,后续要需要补充的再更新,感谢观看 ✿✿ヽ(°▽°)ノ✿
Kotlin基础入门之必知必会,查漏补缺来一手~~~的更多相关文章
- .NET零基础入门09:SQL必知必会
一:前言 仿佛到了更进一步的时候了,每一个程序员迟早都会遇到数据存储的问题.我们拿什么来存储程序产生的数据?举例来说,用什么来存储我们的打老鼠游戏每次的成绩呢?选择如下: 1:内存中.缺点,退出游戏, ...
- 迈向高阶:优秀Android程序员必知必会的网络基础
1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- 第5节:Java基础 - 必知必会(下)
第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...
- 第4节:Java基础 - 必知必会(中)
第4节:Java基础 - 必知必会(中) 本小节是Java基础篇章的第二小节,主要讲述抽象类与接口的区别,注解以及反射等知识点. 一.抽象类和接口有什么区别 抽象类和接口的主要区别可以总结如下: 抽象 ...
- 第3节:Java基础 - 必知必会(上)
第3节:Java基础 - 必知必会(上) 本篇是基础篇的第一小节,我们从最基础的java知识点开始学习.本节涉及的知识点包括面向对象的三大特征:封装,继承和多态,并且对常见且容易混淆的重要概念覆盖和重 ...
- 【SQL必知必会笔记(1)】数据库基础、SQL、MySQL8.0.16下数据库、表的创建及数据插入
文章目录 1.数据库基础 1.1 数据库(database) 1.2 表(table) 1.3 列和数据类型 1.4 行 1.5 主键 2.什么是SQL 3.创建后续练习所需数据库.表(MySQL8. ...
- 【MySQL 基础】MySQL必知必会
MySQL必知必会 简介 <MySQL必知必会>的学习笔记和总结. 书籍链接 了解SQL 数据库基础 什么是数据库 数据库(database):保存有组织的数据的容器(通常是一个文 件或一 ...
- Java面试必知必会(扩展)——Java基础
float f=3.4;是否正确? 不正确 3.4是双精度,将双精度赋值给浮点型属于向下转型,会造成精度损失: 因此需要强制类型转换: 方式一:float f=(float)3.4 方式二:float ...
随机推荐
- 十六:使用JDBC对数据库进行CRUD
一.statement对象介绍 Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可. Statement对象的exe ...
- linux(4)----------ssh config详解
1.概述 ~~ config为了方便我们批量管理多个ssh ~~ config存放在~/.ssh/config .XX代表隐藏目录 ~~ config配置语法 2 ...
- ant的javac任务的相关属性配置
任务和javac命令是相似,它编译两种类型的Java文件1)没有被编译的java文件2)曾经编译过,但是class文件版本和当前对应的java文件版本不匹配的java文件. 1)javac命令支持的参 ...
- 自研 Pulsar Starter:winfun-pulsar-spring-boot-starter
原文:自研 Pulsar Starter:winfun-pulsar-spring-boot-starter 里程碑 版本 功能点 作者 完成 1.0.0 支持PulsarTemplate发送消息&a ...
- Spring笔记(3)
一.JDBC Template基本使用 1.开发步骤 1.1直接使用template 导入spring-jdbc和spring-tx坐标 <!-- JDBC--> <dependen ...
- Java特性和优势
Java特性和优势 简单性 面向对象性 可移植性 高性能 分布式 动态性 多线程 安全性 健壮性
- sed命令的使用
1.sed格式.理解 (1)找谁 干什么 (2)想找谁,就把谁保护起来 2.sed基本操作 操作文件oldboy.txt I am lizhenya teacher! I teach linux. ...
- NOI2021 游记
day -10 开始一天一场NoIP模拟赛,前几场每天挂分很厉害(这么说是因为后面的以前做过) 自省选惨挂以后国赛的知识点就几乎没怎么摸过了,考前发现连manacher都不会写了,反演?又陷入&quo ...
- Spring整合MyBatis小结
MyBatis在Spring中的配置 我们在Spring中写项目需要运用到数据库时,现在一般用的是MyBatis的框架来帮助我们书写代码,但是学习了SSM就要知道M指的就是MyBatis,在此,在Sp ...
- nacos配置中心模块详解
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 配置中心 业务上的配置,功能开关,服务治理上对弱依赖的降级,甚至数据库的密码等,都可能用到动态 ...