系列文章路引 👀


文章目录

  • 系列文章路引 👀
  • 一、基本类型
  • 1.数值类型
  • 2.布尔类型
  • 3.字符型
  • 4.字符串类型
  • 5.val与var的区别
  • 二、数组
  • 1.java与kotlin常规使用对比
  • 2.kotlin size() 与 java length()
  • 3.数组的常用方式
  • 三、区间(kotlin 特有的概念,java没有)
  • 1.开区间 ..
  • 2.左闭右开 util
  • 3.倒叙区间 downTo
  • 4.区间步长 step
  • 5.区间的迭代
  • 6.注意点
  • 三、集合框架
  • 1.kotlin集合框架与java对比
  • 2.使用方式
  • 3.补充Pair 键值对 与 Triple 三个元素
  • 四、函数
  • 1.介绍
  • 2.函数的类型,引用
  • 3.变长参数 vararg
  • 4.多返回值(上面提到的Pair 以及 Triple )
  • 5.默认参数
  • 6.函数传递调用
  • 五、总结



一、基本类型

  • Java:区分基本数据类型以及引用类型, 基本数据类型有byte、short、int、long、float、double、char、boolean,八大基本数据类型。而Kotlin 中没有基础数据类型,只有封装的数字类型,你每定义的一个变量,其实 Kotlin 帮你封装了一个对象,这样可以保证不会出现空指针。
  • Kotlin:基本数值类型(继承了Number)有Byte、Short、Int、Long、Float、Double。Char与Boolean不属于数值类型。

如下:Java与Kotlin类型对比

Kotlin

java

字节

byte/Byte

Byte

整形

Int & Long

int/Integer & long/Long

浮点型

Float & Double

float/Float & double/Double

字符

Char

char/Character

字符串

String

String

1.数值类型

  • Kotlin 的基本数值类型包括 Byte、Short、Int、Long、Float、Double 等和java类似只不过第一个字符是大写。不同于 Java 的是,字符不属于数值类型,是一个独立的数据类型。
  • 装箱和拆箱,kotlin的原则是万物皆对象,所以并没有和java中一样的 int 和 Integer 这种数据类型和引用类型的分别,因此kotlin中只存在数字的装箱,并没有拆箱

类 型

类 型

宽 度

Double

双精度浮点型

64

Float

浮点型

32

Long

长整型

64

Int

整形

32

Short

短整型

16

Byte

字节

8

var a: Double = 2.0
    //F表示单精度浮点型
    var b: Float = 2F
    //L表示长整型
    var c: Long = 1L
    var d: Int = 1
    var e: Short = 1
    var f: Byte = 5

如下:可省略编译类型

//kotlin 默认可识别为Long类型
	var c= 124L

kotlin允许存在隐式转换,必须调用对应的方法进行显示转换!!! 如下

var e = 3.0
    var f = e.toLong()
    var float1 = 1f
    var double1 = float1.toDouble()

kotlin支持无符号类型(表示的范围是 有符号类型去除负数的部分,正数部分乘以2倍)
使用:在正常类型前加U 如下

val g:UInt = 9778u
    val h:UByte = 1u
    val i:UShort = 107u
    val j:ULong = 102435u
    println("Range of Int:[${Int.MAX_VALUE},${Int.MIN_VALUE}]")
    println("Range of UInt[${UInt.MAX_VALUE},${UInt.MIN_VALUE}]")
    //运行结果如下
    Range of Int:[2147483647,-2147483648]
	Range of UInt[4294967295,0]

2.布尔类型

  • Boolean 表示布尔类型,和Java相同有true和false两个值
var value: Boolean = false
	var a: Boolean = false
	var b: Boolean = true
	var result = Boolean
	//输出结果为 value==false
	println("value==$value")
    //输出结果为  a && b
    if (a || !b) {
        println("a==b")
    } 
    if (!a && b) {
        print("a && b")
    }

3.字符型

  • Char:字符型,单引号(’ ')表示字符变量,需要显式转换为数字不饿能直接作为数字
var a: Char = 'a'
	println(a)
	var var1 = a.toByte()
	var var2 = a.toInt()
	var var3 = a.toString()
	var var4 = a.toFloat()
	var var5 = a.toShort()
	println("var1 = $var1 ,var2 = $var2 , var3 = $var3 , var4 = $var4 , var5 = $var5")
	//输出结果为  var1 = 97 ,var2 = 97 , var3 = a , var4 = 97.0 , var5 = 97     97为a的ASCII码值

大小写转换,如下:

var a: Char = 'a'
	// 转换为大写
	a = a.toUpperCase()
	println("$a----------")  //输出结果为 A----------
	// 转换为小写
	a = a.toLowerCase()
	println("$a++++++++++") //输出结果为 a++++++++++

4.字符串类型

字符串用法和java一致,这里引入两个kotlin特有的东西

  • 1.kotlin字符串比较。java比较引用使用"==",比较值类型使用"equals()"。而kotlin比较引用使用"===",比较值类型使用"=="。如下:
val l = "Today is sunny day"
    val m = String("Today is sunny day".toCharArray())
    //kotlin 比较
	//    compare values  true
    println(l==m)
	//    compare references  false
    println(l===m)
    //java 比较
    //    compare values  true
    println(l.equals(m))
	//    compare references  false
	println(l==m)
  • 2.kotlin特有的字符串模板 “”" “”" 可以保持格式。如下:
//函数 trimIndent()  去除空格
    val s = """
        hello
            world 
            nice to meet you
        welcome to china
    """.trimIndent()
    //输出结果
//hello
//    world 
//    nice to meet you
//welcome to china

5.val与var的区别

val:表示只读变量,即赋值之后不可更改。
var:表示可读写变量,赋值之后可更改
解析为java代码后,var修饰与val修饰并没有区别,但是在kotlin里面,val代表只读变量又称作运行时常量

//    可读写变量
    var a: Int = 1
//    只读变量
    val b: String = "hello world"
//    反编译为java代码
	int a = true;
    String b = "hello world";

既然在kotlin里面val修饰都已经不可变了,为什么还称作只读变量(运行时常量呢),不叫常量呢?
我们所熟知的java常量指的是编译时常量,即编译期间才会确定的常量。而运行时常量是指在代码运行时才会确定的常量,不同的运行方式可能获取不同的值,所以叫只读变量(运行时常量)。如下代码所示

//如下 cc具体会返回什么样的值 需要在运行期间 走具体的分支才知道
    var bb = true
    val cc : Int = if (bb){
        1
    }else{
        2
    }

那kotlin具体的常量如何表示呢?使用const关键字,具体内容在后面的章节会讲的到。

二、数组

1.java与kotlin常规使用对比

kotlin

java

整形

IntArray

int[]

整形装箱

Array<Int>

Integer[]

字符

CharArray

char[]

字符装箱

Array<Char>

Character[]

字符串

Array<String>

String[]

代码如下(示例):

//创建一个Int数组
    val arr1 = intArrayOf(1, 2, 3, 4, 5)   //type  IntArray 整形
    val arr2 = arrayOf(1, 2, 3, 4, 5)	   //type  Array<Int> 装箱类型
    val arr3 = IntArray(5) { it + 1 }
    val arr7: Array<String> = arrayOf("array", "string")
	    
    // 创建二维数组  数组需要初始化  int默认为0  String手动初始化为""
    val square = Array(10000) { IntArray(10000) }
    val square1 = Array(10000) { Array<String>(10000) { "" } }
    
	//tostring 打印对象信息  contentToString kotlin特有的方法 打印
    println(arr1.toString())
    println(arr1.contentToString())
    println(arr2.contentToString())
    println(arr3.contentToString())
    println(arr7.contentToString())

	//结果输出
	[I@15db9742
	[1, 2, 3, 4, 5]
	[1, 2, 3, 4, 5]
	[1, 2, 3, 4, 5]
	[array, string]

2.kotlin size() 与 java length()

我们都知道java里面数据获取长度使用length属性,集合使用size()方法。在kotlin里面统一使用size

//    长度  kotlin size  java  length
//kotlin
println(arr1.size)
//java
println(arr1.length)

3.数组的常用方式

for循环以及foreatch

//数组的遍历
    val arr6 = floatArrayOf(1.0f, 2.0f, 3f, 5f)
    for (element in arr6) {
        println(element)
    }
    arr6.forEach { element ->
        println(element)
    }
    arr6.forEach { it ->
        println(it)
    }
    arr6.forEach {
        println(it)
    }
    //判断是否存在值
    val empty = arr6.isEmpty()
    println(empty)

	//判断是否至少存在一个元素   其实内部就是调用了!isEmpty()
    val any = arr6.any()
    println("any is $any")

	//判断一个值存在一个数据
    if (arr6.any { it == 1.0f }){
        println("1.0f exists in variable 'arr6'")
    }

    if (!arr6.any { it == 1.2f }){
        println("1.2f not exists in variable 'arr6'")
    }

三、区间(kotlin 特有的概念,java没有)

1.开区间 …

val intRange=1..10 //[1,10]
val charRange='a'..'z'
val longRange=1L..100L

2.左闭右开 util

val intRangeExclusive=1 until 10 //[1,10)
val charRangeExclusive='a' until 'z'
val longRangeExclusive=1L until 100L

3.倒叙区间 downTo

val intRangeReverse=10 downTo 1 //[10,9,8,...,1]
val charRangeReverse='z' downTo 'a'
val longRangeReverse=100L downTo 1L

4.区间步长 step

val intRangeStep=1 .. 10 step 2 //[1, 3, 5, 7, 9]
val charRangeStep='a' .. 'z' step 2
val longRangeStep=1L ..100L step 5

5.区间的迭代

val intRange = 1..10	
	for (element in intRange){
	     println(element)
	}
	intRange.forEach { it->
	     println(it)
	}
	//类似java for循环
    val arrayOf = arrayOf(1, 2, 3, 4, 5)
    for (i in 0 until arrayOf.size) {
        println(i)
    }

	//和上一种写法相等
    for (i in arrayOf.indices) {
        println(i)
    }

6.注意点

小数的区间是不可数的,所以不能够被打印。但是可以进行包含关系判断

//   小数 区间 是不可数的  不可以进行打印
    val floatRange = 1f..2f
    val doubleRange = 1.0..2.0
    println(floatRange.toString())
    if (1.2f in floatRange){
        println(true)
    }
    // 结果
    1f..2f
    true

三、集合框架

1.kotlin集合框架与java对比

  • 增加了“不可变”集合框架接口
  • 没有另起炉灶,服用java api的所有实现类
  • 提供丰富易用的方法,列如 forEach/map/flatMap
  • 运算级别的支持,简化api的访问

kotlin

java

不可变List

List<T>

List<T>

可变List

Mutable<T>

List<T>

不可变Map

Map<K,V>

Map<K,V>

可变Map

Mutable<K,V>

Map<K,V>

不可变Set

Set<T>

Set<T>

可变Set

MutableSet<T>

Set<T>

kotlin集合框架服用javaAPI,只是使用typealias使用kotlin的包名,具体源码如下

@SinceKotlin("1.1") public actual typealias ArrayList<E> = java.util.ArrayList<E>
@SinceKotlin("1.1") public actual typealias LinkedHashMap<K, V> = java.util.LinkedHashMap<K, V>
@SinceKotlin("1.1") public actual typealias HashMap<K, V> = java.util.HashMap<K, V>
@SinceKotlin("1.1") public actual typealias LinkedHashSet<E> = java.util.LinkedHashSet<E>
@SinceKotlin("1.1") public actual typealias HashSet<E> = java.util.HashSet<E>

2.使用方式

除了java的常规使用方式,kotlin可直接使用listOf或者mutableListOf等创建,listOf创建的是Kotlin的List接口不可变的,不可以进行增删,mutableListOf返回对应的ArrayList,是可变的
MutableMapOf源码 默认返回了LinkedHashMap 该类继承HashMap是基于HashMap和双向链表来实现的。 线程不安全 但是可以保证插入时的顺序 且效率和HashMap没有区别 所以kotlin默认返回了LinkedHashMap

//    不可修改  不能添加或者删除元素
    val intList: List<Int> = listOf(1, 2, 3, 4, 5, 6, 7)
//    可以修改
    val mutableList: MutableList<Int> = mutableListOf(1, 2, 3, 4, 5, 6, 7, 8)

//    map
    val map = mapOf<String, Any>("name" to "zxf", "age" to 18)
    val map2 = mutableMapOf<String, Any>("name" to "liSi", "age" to 22)
//    java  get操作
    val name = map["name"]
//    java  set操作
    map2["name"] = "王五"
//	  MutableList源码  默认返回了ArrayList
public fun <T> mutableListOf(vararg elements: T): MutableList<T> =
    if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
//    MutableMapOf源码  默认返回了LinkedHashMap  该类继承HashMap是基于HashMap和双向链表来实现的。  线程不安全  但是可以保证插入时的顺序  且效率和HashMap没有区别  所以kotlin默认返回了LinkedHashMap
public fun <T> mutableListOf(vararg elements: T): MutableList<T> =
    if (elements.size == 0) ArrayList() else ArrayList(ArrayAsCollection(elements, isVarargs = true))
//	  mutableMapOf测试使用
	val map2 = mutableMapOf<String, Any>("name" to "liSi", "age" to 22)
	map2.put("sex","boy")
    map2.put("height",172)
//    修改name值
    map2["name"] = "zzz"
    map2.forEach{
        println("key:${it.key}-----value:${it.value}")
    }
//    结果输出  顺序不变
    key:name-----value:zzz
    key:age-----value:22
    key:sex-----value:boy
    key:height-----value:172

也可以直接生成集合对象使用

val stringList = ArrayList<String>()
//    add
    for (i in 0..10) {
        stringList.add("num:$i")
    }
    for (i in 0..10) {
        stringList += "num:$i"
    }
//    remove
    for (i in 0..10) {
        stringList.remove("num:$i")
    }
    for (i in 0..10) {
        stringList -= "num:$i"
    }

3.补充Pair 键值对 与 Triple 三个元素

Pair 键值对对象
Triple 三个元素
可通过属性拿到值,也可以通过解构获取结果。
解构具体在后面的章节会讲到,具体先看用法

//    Pair  键值对
    val pair = "name" to "zxf"
    val pair1 = Pair("name", "zxf")
//    获取pair  对应的元素
    val first = pair.first
    val second = pair.second
//    解构
    val (x, y) = pair
    println("x:$x----y:$y")
    
//    Triple  三个元素
    val triple = Triple<String, Int, Int>("zxf", 1, 1)
    val first1 = triple.first
    val second1 = triple.second
    val third = triple.third

    val (g, t, z) = triple
    println("g:$g----t:$t----z:$z")
//	  输出
	x:name----y:zxf
	g:zxf----t:1----z:1

四、函数

1.介绍

  • kotlin函数有自己的类型,被誉为“一等公民”
  • 可以赋值、传递、并在合适的条件下使用(Unit 相当于 java里面的void)
  • java里面的方法可以理解为函数的一种类型,自带receiver。(方法可以理解为放在类里面的函数,receiver则指的是对应类的实例化)。

2.函数的类型,引用

函数是有类型的,比如

fun foo(){} 的类型就是 ()-> Unit,代表无参无返回值

fun foo(p0:Int):String{…} 的类型是 (Int)->String, 需要int类型的参数,返回String类型

class Foo{ fun foo(p0:Int):String{…} } 的类型是Foo.(Int)->String , 代表receiver是Foo,需要int参数,返回String类型。类型也可以表示为(Foo,Int)->String 和 Function3(Foo,Int,String)

kotlin Android 如何知道当前app有多少个activity运行 kotlin类型判断_android

函数的引用 receiver::functionname,如下所示

kotlin Android 如何知道当前app有多少个activity运行 kotlin类型判断_android_02


kotlin Android 如何知道当前app有多少个activity运行 kotlin类型判断_List_03

class Foo {
    fun bar(p: String, p0: Int) {
        println("$p,$p0")
    }
}
//    可变参数
fun main(vararg args: String) {
    println(args.contentToString())

//    函数引用传递
    val x = Foo::bar
    val w: Foo.(String, Int) -> Unit = Foo::bar
    val y: (Foo, String, Int) -> Unit = x
    val z: Function3<Foo, String, Int, Unit> = x
//    Foo.(String, Int) -> Unit = (Foo, String, Int) -> Unit = Function3<Foo, String, Int, Unit>
}

3.变长参数 vararg

fun varargParameter(vararg p: String) {
	    println("可变长参数:${p.joinToString(":")}")
	}
	//调用
	varargParameter("a","b","c","d","e","f")

4.多返回值(上面提到的Pair 以及 Triple )

利用解构接收,简化代码

//    多返回值
fun multiReturnValues(): Triple<String, Int, Int> {
    return Triple("zxf", 1, 1)
}
//    利用 Triple  或者 pair  可实现伪多返回值
val (q, h, e) = multiReturnValues()
println("q:$q,h:$h,e:$e")

5.默认参数

kotlin Android 如何知道当前app有多少个activity运行 kotlin类型判断_java_04

//    默认参数
fun defaultParameter(p: Int = 0, p0: String, p1: Float = 1f): Int {
    return p
}
//    默认参数  如果传入的参数 不是默认第一个 可指定参数名字传递
 val defaultParameter = defaultParameter(p0 = "hello")
 println(defaultParameter)

6.函数传递调用

看如下例子,首先利用函数的类型声明函数,在引用对应的函数,当作参数传递

// 需要一个receiver为Foo,参数为String、Int 返回类型为Unit的函数
fun yy(p: (Foo, String, Int) -> Unit) {
	//调用p  第一个参数为 对应的recevier
    p(Foo(), "hello", 1)
}
// receiver 为Foo 参数为String、Int 无返回类型
class Foo {
    fun bar(p: String, p0: Int) {
        println("$p,$p0")
    }
}
// 引用 传参 调用yy函数
fun main(vararg args: String) {
	val foo : Foo.( String , Int ) -> Unit = Foo::bar
	//上下等价
	//val foo : (Foo , String , Int ) -> Unit = Foo::bar	
	yy(foo)
}
// 输出结果
hello,1

五、总结

以上学习完毕后,可实现简单的demo,将知识融会贯通,如下 简单的四则运算 看看和java实现有如何的区别。

fun main(vararg args: String) {

    computer("1", "+", "1")

}

fun computer(vararg args: String) {
    if (args.size < 3) {
        return showHelp()
    }

    val map = mapOf(
        "+" to ::add,
        "-" to ::reduce,
        "*" to ::multiply,
        "/" to ::eliminate
    )

//    如果为null  则返回
    val kFunction2 = map[args[1]] ?: return showHelp()

    try {
        println("Input:${args.joinToString(" ")}")
        println("Output:${kFunction2(args[0].toInt(), args[2].toInt())}")
    } catch (e: Exception) {
        println("Invalid Arguments")
        showHelp()
    }
}

fun add(p: Int, p1: Int): Int {
    return p + p1
}

fun reduce(p: Int, p1: Int): Int {
    return p - p1
}

fun multiply(p: Int, p1: Int): Int {
    return p * p1
}

fun eliminate(p: Int, p1: Int): Int {
    return p / p1
}

fun showHelp() {
    val content = """
        Simple Template
            Input:3 * 5
            Output:15
    """.trimIndent()
    println(content)
}