Kotlin探究之旅-基础篇
Kotlin探究之旅-基础篇
每一个进入IT行业的人,想必或多或少都会了解一点关于Oracle和Google的爱恨情仇,关于Java的版权问题
,Oracle已经和Google纠缠了多年了,而最近,这场持续了多年的纠纷似乎以Google的败诉而告一段落了!
作为一个Android开发人员,跟着Google混饭吃的我们,应该都很清楚,随着这场官司的败诉,Java随时都有可能从Android主要支持语言的宝座上退下来,届时,作为占领全球百分之七十以上手机系统的Android,必定会选择一门新的语言作为其主要支持语言,无疑,Kotlin
的出现,让一切变得没有了争议
在2017年的IO大会上,Google便宣布了,将Android开发的官方语言更换为了Kotlin
那么Kotlin是何许人也,为何能兵不血刃的取代Java这位自Android出生以来便寸步不离的老大哥呢?
下面,便让IT烟酒僧
同学给你介绍一下Kotlin
这位新同学
Kotlin是由 JetBrains
开发的一门同样基于JVM设计的编程语言,自诞生起,便受到了业界各位大神的追捧和赞扬,其中就包含烟酒僧最崇拜的Jake大神
。
不过,既然能受到如此高的待遇,想必Kotlin也必非浪得虚名,毕竟程序猿是一群非常看重效率的群体,的确,Kotlin也对得起这份待遇,相对Java来说
kotlin占据了代码简洁高效、函数式编程、空指针安全、支持lambda表达式、流式API
等优势。
而且,Kotlin和Java是互相完美兼容
的,两种代码文件可以并存,代码可以互相调用、文件可以互相转换,库文件也可以无障碍地互相调用,据说使用Kotlin基本不会带来额外的成本负担
。
是不是很 perfect
,是不是已经忍不住想认识一下Kotlin了,下面,就让IT烟酒僧
同学带你走进kotlin的世界,从基础开始认识kotlin这位It界的新面孔。
一 数据类型
var 代表变量 可以被修改
变量的声明以及智能类型推断
var i = 10;
i = 19;
//i=99999999999;(超出int的取值范围,报错)
var j = 999999999999999;
var s = "haha"
//显式(指定数据类型)
var i2 : Int =19;
var i3:Byte =127;
//i3=257;(超出byte的取值范围,报错)
val 常量,只读,不可以被修改
val a="no"
//a="s" 变量不能被修改
变量的取值范围
kotlin中更常见的容器
Byte 存储值范围 整数 -128–127
Short 存储值范围 整数 -32768–32767
Int 存储值范围 整数 -2147483648–2147483647
Long 存储值范围 整数 -9223372036854775807–9223372036854775807
Float 存储值范围 小数,小数点可以精确到6位
Double 存储值范围 小数 小数点可以精确到15–16位
String 存储值范围 字符串,用”“双引号引起来的字符串都可以存
//Byte
val aByte: Byte=Byte.MAX_VALUE
val bByte: Byte=Byte.MIN_VALUE
println("byte的最大值:"+aByte)
println("byte的最小值:"+bByte)
//Long
val along: Long=Long.MAX_VALUE
val blong: Long=Long.MIN_VALUE
println("Long的最大值:"+along)
println("Long的最小值:"+blong)
//二进制
val aInt: Int=0b0011
println("aInt的值"+aInt)
函数入门(偶函数,奇函数.三角函数,幂函数)
计算机的函数就是程序执行的小片段,这些小片段有机的组合在一起就会执行一个业务
//利用函数打印菱形
printlStart()
fun printlStart(){
println("*")
}
//布尔运算
booleanTest()
fun booleanTest(){
var num1=4
var num2=6
println(num1>num2)//------false
println(num1<num2)//______true
//根号5/4/3
var num3 = Math.sqrt(5.0)-Math.sqrt(4.0)
var num4 = Math.sqrt(4.0)-Math.sqrt(43.0)
println(num3>num4)
//次方(2的100次方)
var num5 = Math.pow(2.0, 100.0)
var num6 = Math.pow(3.0, 75.0)
println(num5>num6)
}
交互式编程
kotlin和java都是基于JVM的
配置环境变量jdk kotlinc
kotlin函数的编写规则
fun 函数名(参数名:参数类型):返回值类型{函数体}
如果返回值类型为Unit 则可以省略
二 字符串(String)/条件控制语句
1 加减乘除
var a = 8
var b = 2
println("a+b==" + plus(a, b))
println("a-b==" + sub(a, b))
println("a*b==" + mutl(a, b))
println("a/b==" + devide(a, b))
//加法运算
fun plus(a: Int, b: Int): Int {
return a + b
}
//减法运算
fun sub(a: Int, b: Int): Int {
return a - b
}
//乘法法运算
fun mutl(a: Int, b: Int): Int {
return a * b
}
//除法运算
fun devide(a: Int, b: Int): Int {
return a / b
}
2字符串的比较
Kotlin中的相等运算符有三个 ==, ===, equals()
Kotlin 中的 == 等同于调用 equals() 函数, 默认比较的是两个对象的HashCode.
比较两个对象引用是否相等要用 === 操作符.
var strq1 = "张三"
var str2 = "张三"
var an="Android"
var and = "android"
println(strq1==str2)// true
/**
* 下面的第二个参数(true/false)
* 如果是false 表示不忽略大小写
* 如果是true 表示忽略大小写
*/
println(an.equals(and,false)) //打印出来为false
println(an.equals(and,true)) //打印出来为true
如果两个字符串内容相同那么 ==, equals return true.
如果两个医用相等则 === return true.
// 字符串比较.
private fun test1() {
val s1 = "Doug"
// 使用这种方式创建就是为了创建两个地址不同的字符串。
val s2 = String(charArrayOf('D', 'o', 'u', 'g'))
println(s1)
println(s2)
// 如果两个字符串的值相同那么hashCode也相等.说
println(s1.hashCode())
println(s2.hashCode())
// == <==> equals , 比较的都是字符串的值。
println(s1 == s2)
println(s1.equals(s2))
// === 比较两个对象的引用是否相同。
println(s1 === s2)
}
如果没有重写 equals 方法那 === 和 == 一样的返回的都是比较引用.
可以重写 equals 然后添加自己的逻辑
class Person(val name:String) {
/**
* equals 通用写法.
*/
override fun equals(other: Any?): Boolean {
return when (other) {
!is Person -> false
else -> this === other || this.name == other.name
}
}
}
3 String中的占位符${}
/日记生成器(接收参数是地点,返回内容)
/**
* ${} string中的占位符
*/
fun diaryGenerater(placeName: String): String {
var temple = """今天天气晴朗,万里无云,我的小金鱼淹死了,${placeName} ${placeName.length}个字"""
return temple
}
调用
var diaryGenerater = diaryGenerater("我好伤心")
println(diaryGenerater)
4条件控制语句(if/else)
fun checkFace(score: Int) {
if (score > 80) {
println("这是一个帅哥")
} else {
println("这是一个衰哥")
}
}
//返回两个数中最大的那个
fun returnBig(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
也可以写成这样
fun maxOf(a: Int, b: Int) = if (a > b) a else b
String占位符和条件控制语句的联合调用
println("${10}和${12}中较大的那个值为${returnBig(4, 6)}")
三 字符串与数字之间的转换
var a="13"
var b=13
//数字转字符串
a=b.toString()
//字符串转数字
b=a.toInt()
var c="a3"
b=c.toInt()//编译不报错,但是运行会报NmuberFormatException
四 kotlin对于空指针的处理
kotlin中
?:表示当前是否对象可以为空
!!: 表示当前对象不为空的情况下执行
使用一个返回值为空的函数:
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// ...
if (x == null) {
println("Wrong number format in arg1: '${arg1}'")
return
}
if (y == null) {
println("Wrong number format in arg2: '${arg2}'")
return
}
// x 和 y 将会在空值检测后自动转换为非空值
println(x * y)
}
五 区间/for循环/步长/反转/总数
1 区间
声明了一个数组,数组中的值为1,2,3…100
var nums=1..100
var num=1..100 //闭区间 [1,100]
var num2=1 until 100 //开区间[1,100)
2 for循环
利用 in 将区间中的值取出来
var nums=1..100
var result=0
for (num in nums){
result+=num
}
println("结果:${result}")
3 步长 (step)
var nums1=1..16
for (a in nums1 step 2){ //step 步长
println(a) //1,3,5,7,9,11,13,15
}
4 反转(reversed)
var nums1=1..16
var reversed = nums1.reversed()
for (a in reversed){
println(a)//15,13,11,9,7,5,3,1
}
5 总数(count)
println("总数为:"+reversed.count())
六 when表达式
和java中的switch有异曲同工之处,但比switch更加强大,更加方便
//学生考试成绩
fun gradeStudent(score:Int) {
when (score) {
10 -> println("考了满分")
9 -> println("干的漂亮")
8 -> println("还可以")
7 -> println("还需努力")
6 -> println("刚及格")
5 -> println("你完了")
}
}
调用
gradeStudent(9)
还可以这样用
//数字长度
fun numTochinese(num:Int):String{
var result=when(num){
1->"一"
2->"二"
3->"三"
4->"四"
5->"五"
6->"六"
else->num.toString()
}
return result
}
调用
//日记
fun diaryGenerator(placeName:String){
var diary="""今天天气不错,我们去${placeName}游玩,首先映入眼帘的是,${placeName} ${numTochinese(placeName.length)}个鎏金大字"""
println(diary)
}
diaryGenerator("颐和园")
七 人机交互之键盘输入/try
while (true) {
println("欢迎使用我的计算器")
println("请输入第一个数字")
var number1 = readLine()
println("请输入第二个数字")
var number2 = readLine()
//如果这样直接输出,会被当成是string类型的
println("${number1}+${number2}=${number1 + number2}")
try {
//在类型后面跟?表示这个对象可能为空,跟!!表示这个类型一定不为空
var num1: Int = number1!!.toInt()
var num2: Int = number2!!.toInt()
println("${num1}+${num2}=${num1 + num2}")
} catch (e: Exception) {
println("大哥请输入数字额")
}
}
八 集合
1 声明List集合
var lists = listOf<String>("买鸡蛋", "买大米", "买杜蕾斯")
正常打印
for (list in lists) {
println(list)
}
按位置打印list中的数据
for ((i, e) in lists.withIndex()) {
println("$i $e")
//-----0 买鸡蛋
//-----1 买大米
//-----2 买杜蕾斯
/**
* so i 代表索引位置,e 代表索引对应的值
*/
}
2 声明Map集合
var map = TreeMap<String, String>()
map["好"] = "good"
map["学习"] = "study"
map["天"] = "day"
map["向上"] = "up"
获取里面的内容
println(map["好"]) //----------good
九 递归/尾递归优化
阶乘
fun fact(num:Int):Int{
if (num==1){
return 1
}else {
return num * fact(num - 1)
}
}
调用
println("${fact(10)}")
相加
fun add(num:Int):Int{
if (num==1){
return 1
}else{
return num+ add(num-1)
}
}
调用
println("${add(100)}")
尾递归优化时返回的需要时函数本身
同样是相加
tailrec fun adds(num:Int,result:Int):Int{
println("计算机运行了第${num}次,result=${result}")
if (num==0){
return 1
}else{
return adds(num-1,result+num)
}
}
调用
var result=0
println(adds(10000,result))
十 函数
定义一个函数接受两个 int 型参数,返回值为 int :
fun sum(a: Int , b: Int) : Int{
return a + b
}
fun main(args: Array<String>) {
print("sum of 3 and 5 is ")
println(sum(3, 5))
}
函数表达式
var i={x:Int,y:Int ->x+y}
var result=i(3,5)
函数的第二种声明
var j:(Int,Int)->Int={x,y->x+y}
var result2=j(3,5)
如果大括号中的业务逻辑只有一行,可以将大括号省略,然后直接返回函数(如add)
fun add(x:Int,y:Int):Int{
return x+y
}
Unit 的返回类型可以省略:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
fun main(args: Array<String>) {
printSum(-1, 8)
}
函数只有一个表达式函数体以及一个自推导型的返回值:
fun add1(x:Int,y:Int):Int=x+y
fun a(x:Int,s:Int):Boolean=x>s
或者
fun sum(a: Int, b: Int) = a + b
您的支持是我创作最大的动力
更多精彩内容,请扫描下面二维码关注作者微信公众号 IT烟酒僧