【Kotlin】 自学(二)-内置类型

681 阅读4分钟

1.基本类型

Kotlin相对于Java来说少,Java中除了基本类型还有包装类,但是在Kotlin中都是包装类

KotlinJava
字节Bytebyte/Byte
整型Int&Longint/Integer&long/Long
浮点型Float&Doublefloat/Float&double/Double
字符Charchar/Character
字符串 String String

上面那张图对比的很明显了,这里就不多说了,接下来我们要是说的是在Kotlin中如何声明变量

1.1声明变量

kotlin中声明变量有两种valvar

	val b: String = "Hello Kotlin"

val:修饰符,b:变量名,String:类型,Hello Kotlin:变量初始化的值

这两个有啥区别呢?就是说val声明的变量我们在下面使用的时候是不能更改它的值的,var声明的可以,val声明的类似我们Java中的final修饰的, Java

	int a = 2;
	final String b = "Hello Java"

Kotlin

	var a: Int = 2
	val b: String = "Hello Kotlin"

我们这么一看,哟呵,在Kolin中声明一个变量的字符数居然比Java多!其实不是的,这里就要说下Kotlin中的类型推导了,Kotlin可以根据等号右侧的值推导出来这个变量的类型,所以说其实我么没必要把类型写出来,像下面的就可以了

	var a = 2
	val b = "Hello Kotlin"

1.2 易混淆的Long类型标记

Java中声明一个Long类型的变量,我们通常在值的后面加上L或者l,但是这个l很容易和大写的I或者1混淆,在Kotlin中就必须使用L,你使用小写的l是编译不过去的 在这里插入图片描述

1.3 数值类型转换

Java中我们可以把一个Int类型的变量赋值给一个Long类型的变量,直接用=号即可,但是在Kotlin中是不行的,我们必须调用它的转换方法 在这里插入图片描述 我们直接用=号编译器直接提示错误,那我们应该怎么做呢?

	val e: Int = 10
	val f: Long = e.toLong()

1.4 无符号类型

这个我们Java中是没有的,但是C有,Kotlin兼容C就有了这个类型

有符号类型无符号类型
字节ByteUByte
短整型ShortUShort
整型IntUInt
长整型LongULong
字符串 String String

1.5 字符串

基本上和Java中的一样,这里就说一些不一样的

1.5.1 """ """声明字符串

Kotlin中我们可以使用三个双引号在声明字符串,我们在这里声明什么样,打印出来就是什么样 在这里插入图片描述

1.5.2 字符串模板

字符串模板以美元符号$开头,其中包含变量名称或花括号中的任意表达式。 在这里插入图片描述 在这里插入图片描述

1.5.3 字符串比较

Java中比较两个字符串用equals==,kotlin中分别对应的是===== 在这里插入图片描述

数组

KotlinJava
整型IntArrayint[]
整型装箱Array<Int>Integer[]
字符CharArraychar[]
字符装箱Array<Char>Character[]
字符串 Array<String> String[]

数组创建

我们在Java中创建数组通过new关键字来创建

		int[] c = new int[]{1, 2, 3, 4, 5};
		String[] d = new String[]{"Hello", "World"};

Kotlin中不同,通过arrayOf或者对应的xxxArrayOf即可

 		val c0 = intArrayOf(1, 2, 3, 4, 5)
 		val c1 = IntArray(5) { it + 1 } 
	 	val d = arrayOf("Hello", "World")

数组长度

Java中拿到一个数组的长度我们通过length方法

		int[] a = new int[5];
		System.out.println(a.length);

Kotlin中通过size方法

 		val a = IntArray(5)
 		println(a.size)

数组读写

这个javaKotlin基本上一样,都是通过下标获取

 		String[] d = new String[]{"Hello", "World"};
 		d[1] = "Java";
 		System.out.println(d[0] + ", " + d[1]);
		val d = arrayOf("Hello", "World")
		d[1] = "Kotlin"
		println("${d[0]}, ${d[1]}")

数组遍历

Java中通过for循环遍历

		float[] e = new float[]{1, 3, 5, 7};
        for (float element : e) {
            System.out.println(element);
        }

        for (int i = 0; i < e.length; i++) {
            System.out.println(e[i]);
        }

Kotlin中也可以通过for循环,但是有更简单的

		val e = floatArrayOf(1f, 3f, 5f, 7f)
    	for (element in e) {
        	println(element)
    	}

    	e.forEach {
        	println(it)
    	}

数组包含关系

如何判断某个元素是否在数组中呢?比如1f是否在数组中,1.2f是否不在数组中 Java写法

 		for (float element : e) {
            if(element == 1f){
                System.out.println("1f exists in variable 'e'");
                break;
            }
        }

        //Test not in an Array
        boolean exists = false;
        for (float element : e) {
            if(element == 1.2f){
                exists = true;
                break;
            }
        }

        if(!exists){
            System.out.println("1.2f not exists in variable 'e'");
        }

Kotlin写法


    if (1f in e) {
        println("1f exists in variable 'e'")
    }

    if (1.2f !in e) {
        println("1.2f not exists in variable 'e'")
    }

区间

区间创建

通过..来创建的区间是闭区间,包含两端

 	val intRange = 1..10 // [1, 10]
    val charRange = 'a'..'z'
    val longRange = 1L..100L
    //不可数
    val floatRange = 1f .. 2f // [1, 2]
    val doubleRange = 1.0 .. 2.0
	//无符号
    val uintRange = 1U..10U
    val ulongRange = 1UL..10UL

开区间

通过until创建的区间包左不包右

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

倒叙区间

通过downTo创建,包含两侧的值,闭区间

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

区间步长

通过step即可设置区间的步长,比如我设置step 2,原来是1,2,3,4,5,6,7,8,9,10,现在就变成了1,3,5,7,9

	val intRangeWithStep = 1..10 step 2
    val charRangeWithStep = 'a'..'z' step 2
    val longRangeWithStep = 1L..100L step 5

注意:不可数的集合不能设置步长

区间遍历

和数组一样

 	for (element in intRange) {
        println(element)
    }

    intRange.forEach {
        println(it)
    }
	
	for(i in array.indices){
        println(array[i])
    }

区间包含关系

和数组一样

 	if (3.0 !in doubleRange) {
        println("3 in range 'intRange'")
    }

    if (12 !in intRange) {
        println("12 not in range 'intRange'")
    }

集合

KotlinJava
不可变ListList<T>List<T>
可变ListMutableList<T>List<T>
不可变MapMap<K,V>Map<K,V>
可变MapMutableMap<K,V>Map<K,V>
不可变SetSet<T>Set<T>
可变SetMutableSet<T>Set<T>

集合创建

Java

        List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4));

Kotlin

	//不可变List 不能添加删除元素
    val intList: List<Int> = listOf(1, 2, 3, 4)
    //可变List 可以添加删除元素
    val intList2: MutableList<Int> = mutableListOf(1, 2, 3, 4)
	//Any 类似Java中的Object
    val map: Map<String, Any> =
        mapOf("name" to "Greathfs", "age" to 20)
    val map2: Map<String, Any> =
        mutableMapOf("name" to "Greathfs", "age" to 20)

to相当于K,V

集合修改

Java

 		for (int i = 0; i < 10; i++) {
            stringList.add("num: " + i);
        }

        for (int i = 0; i < 10; i++) {
            stringList.remove("num: " + i);
        }

Kotlin

 	for (i in 0 .. 10){
        stringList.add("num: $i")
    }

    for (i in 0 .. 10){
        stringList += "num: $i"
    }

    for (i in 0 .. 10){
        stringList -= "num: $i"
    }

这里+=相当于add,-=相当于remove

集合读写

Java中通过get/set方法来进行读写,map写的话用的是put

 		stringList.set(5, "HelloWorld");
        String valueAt5 = stringList.get(5);

        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("Hello", 10);
        System.out.println(hashMap.get("Hello"));

Kotlin中的ListJava类似,map稍有不同

	stringList[5] = "HelloWorld"
    val valueAt5 = stringList[5]

    val hashMap = HashMap<String, Int>()
    hashMap["Hello"] = 10
    println(hashMap["Hello"])

这个[]里面对应的就是key,等号右边对应的就是value

集合遍历

		//List
 		var mutableList: MutableList<Int> = mutableListOf(1, 2, 3, 4)
        mutableList.forEach {
            println("Mutable List Elements:$it")
        }

        for (value in mutableList) {
            print("value:$value")
        }

		//map
		 var mutableMap: MutableMap<Int, String> = mutableMapOf(1 to "one", 2 to "two", 3 to "three")
        mutableMap.forEach {
            print("key:${it.key}...value:${it.value}")
        }
        for ((key, value) in mutableMap) {
            print("Key:$key....Value:$value")
        }

PairTriple

	//创建
 	val pair = "Hello" to "Kotlin"
    val pair = Pair("Hello", "Kotlin")

    val first = pair.first
    val second = pair.second
    //结构表达式
    val (x, y) = pair
	//创建
	val triple = Triple("x", 2, 3.0)
	
    val first = triple.first
    val second = triple.second
    val third = triple.third
    //结构表达式
    val (x, y, z) = triple

函数

函数定义

	fun main(args: Array<Stirng>): Unit {
		println(args.contrnyToString())
	}

fun关键字声明,然后是函数名,函数的参数列表,函数返回值,如果可以推导出函数返回值,这里可以省略

函数和方法区别

  • 方法可以看错是函数的一种特殊类型
  • 从形式上看,有receiver的函数就是方法

我们举个例子

	//函数
	fun main(vararg args: String): Unit {
  
	}

	class Foo {
    	//方法
    	fun bar(p0: String, p1: Long): Any {
        TODO()
    	}
	}

我们看下上面的例子,什么是receiver呢?我们一般调用某个方法都必须实例化它对应的类,那个就是receiver,而函数不一样,函数可以直接使用,比如我们想调用上面的bar方法,我们需要这样

 Foo().bar("hello",10)

两者相似,但是稍有不同

函数类型

	//类型 () -> Unit
	fun foo(){}
	//类型 (Int) -> String
	fun foo(p0: int): String{...}
	class Foo {
		//类型 Foo.(String,Long) -> Any 等价 (Foo,String,Long) -> Any 
		//Foo.(String,Long) -> Any 这个Foo就是bar方法的receiver
		fun bar(p0: String, p1: Long): Any{...}
	}

函数引用

	fun foo() {}
	fun foo(p0: Int): String {
    	TODO()
	}
	class Foo {
    	fun bar(p0: String, p1: Long): Any {
        	TODO()
    	}
	}

对应的引用就是

 	::foo
 	::foo
 	Foo::bar

有引用我们就可以使用变量接收

	val f: () -> Unit = ::foo
    val g: (Int) -> String = ::foo
    //下面几种等同
    val h: (Foo, String, Long) -> Any = Foo::bar
    val j: Foo.(String, Long) -> Any = Foo::bar
    val k: Function3<Foo, String, Long, Any> = Foo::bar
   

这里注意下带有receiver的,以上面那个例子为例,加入我们先实例化出来Foo对象,那写法就会不一样

	val foo = Foo()
    val m: (String, Long) -> Any = foo::bar

变长参数

关键字vararg

	fun multiParameters(vararg ints: Int) {
    	println(ints.contentToString())
}

默认参数

	//声明默认值
	fun defaultParameter(x: Int,y: String,z: Long = 0L){}
	//函数调用
	defaultParameter(5,"Hello")

注意,这里默认要声明在最后一个,如果你不想这样,还可以用下面这种方式

具名参数

	//声明默认值
	fun defaultParameter(x: Int = 5,y: String,z: Long = 0L){}
	//函数调用 形参y来显示接收参数
	defaultParameter(y="Hello")