for循环和foreach
val str="abcde"
//这个就相当于java中的高级for循环,
// 但是java中的高级for循环不能用于字符串
for (c in str) {
println(c)
}
//带角标
for ((index,c) in str.withIndex()) {
println("index=$index c=$c")
}
str.forEach {
println(it)
}
str.forEachIndexed { index, c ->
println("index=$index c=$c")
}
continue和break
- continue跳出本次循环
- break跳出循环
- 不能用在foreach里面
标签处返回
val s1="abc"
val s2="123"
tag3@ for (c1 in s1) {
for (c2 in s2) {
println("$c1 $c2")
if(c1=='b' && c2=='2'){
break@tag3
}
}
}
//当组合为b2时,我想结束双层for循环,break和continue都不能满足需求,其实return可以,但是return其实结束了方法,如果后面还有代码是执行不到的。所以这里用标签处返回。
while和do while
这里有个需求,打印1-100.其实在java里我们可以用for循环,比如for(int i=0;i<100;i++)……但是kotlin中想用for循环,必须先在数组或者集合中保存1-100,再使用for循环。这样不太好,所以用到了while.
//while和do while的区别在于先判断还是先执行,与java一样
var a=100
while (a>0){
println(a)
a--;
}
do {
print(a)
a++
}while (a<=100)
区间
- 概念:
数学中对于区间的定义是一段实数范围,有 开区间、闭区间、半开半闭。而kotlin中区间不仅仅指实数范围,还有字符范围。
- 定义
//有三种方式定义区间,下面用了三种方式分别定义了三种类型的区间.
val range1=1..100
val range2=IntRange(1,100) //通过对象方式进行定义
val range3=1.rangeTo(100)
val range4=1L..100L
val range5=LongRange(1L,100L)
val range6=1L.rangeTo(100L)
val range7='a'..'z'
val range8=CharRange('a','z')
val range9='a'.rangeTo('z')
- 区间的遍历:for、foreach循环即可
for (i in range1) {
println(i)
}
for ((index,i) in range1.withIndex()) {
}
- 反向区间和区间的反转
//定义反向区间
val range1=100 downTo 1
//区间的反转
val range2=101..200
val range3=range2.reversed()
数组
- 定义
//方式一
val arr1= arrayOf("张三","李四")
val arr2= arrayOf(10,20,30)
val arr3= arrayOf('a','b','c')
val arr4= arrayOf('a',"张三",30)
//方式二,仅限于八种基本数据类型的数组
val arr5=IntArray(10)
//创建数组,并把里面每个元素初始化为30
val arr6=IntArray(10){
30
}
//字符串数组只能通过arrayof方式创建
- 数组的遍历:for、foreach即可
- 数组元素修改
//需求:把20修改为200
val arr2= arrayOf(10,20,30)
//方式一
arr2[1]=200
//方式二
arr2.set(1,200)
for (i in arr2) {
println(i)
}
- 数组元素角标查找
val arr1 = arrayOf("百里屠苏", "欧阳锋", "郭靖", "百里屠苏", "陵越", "欧阳少恭")
//返回对应元素(百里屠苏)第一次出现的角标,如果没有找到返回-1
arr1.indexOf("百里屠苏")
//返回对应元素(百里屠苏)最后一次出现的角标,如果没有找到返回-1
arr1.lastIndexOf("百里屠苏")
//查找第一个姓“欧阳”人的位置
val index3=arr1.indexOfFirst {
it.startsWith("欧阳")
}
println(index3)
//查找最后一个姓“欧阳”人的位置
val index4=arr1.indexOfLast {
it.startsWith("欧阳")
}
//查找欧阳少恭第一次出现的位置
val index5=arr1.indexOfFirst { it=="欧阳少恭" }
println(index5)
When表达式
java中的switch支持char、int、byte、short、String(jdk高版本)、枚举。
Kotlin中when表达式原理:简单的when表达式通过switch实现,复杂的when表达式通过 if else实现。
when表达式返回值在{}最后一行。
//简单的when表达式
fun todo(age:Int):String{
when(age){
7->{
return "开始上小学"
}
12->{
return "开始上中学"
}
15->{
return "开始上高中"
}
18->{
return "开始上大学"
}
else->{
return "不知道"
}
}
}
//复杂的when表达式
fun todo(age:Int):String{
when(age){
// 1,2,3,4,5,6->{
// return "准备上小学"
// }
in 1..6->{
return "准备上小学"
}
7->{
return "开始上小学"
}
12->{
return "开始上中学"
}
15->{
return "开始上高中"
}
18->{
return "开始上大学"
}
else->{
return "不知道"
}
}
}
//when表达式不带参数
fun todo1(age:Int):String{
when{
age in 1..6->{
return "准备上小学"
}
age==7->{
return "开始上小学"
}
age==12->{
return "开始上中学"
}
age==15->{
return "开始上高中"
}
age==18->{
return "开始上大学"
}
else->{
return "不知道"
}
}
}
函数表达式
函数体只有一行代码,可以省略return,用=代替,返回值类型也可以不用写.最终就是一个函数表达式。
//fun add(a:Int,b:Int):Int{
// return a+b
//}
fun add(a:Int,b:Int)=a+b
fun hello()= println("hello")
函数引用和匿名函数
//::获取函数的引用
val padd=::add
//通过padd调用函数
padd(10,20)//方式一
padd.invoke(10,20)//方式二,可以处理函数变量为空的情况
//匿名函数
val padd1:(Int,Int)->Int={a,b->a+b}
默认参数和具名参数
解决了java中函数重载的问题。
fun sendRequest(path:String,method:String="GET"){
}
可变参数
//java中的可变参数
public int add(int... a){
int result=0;
for(int i:a){
result +=i;
}
return result;
}
//Kotlin可变参数
fun add1(vararg a:Int):Int{
//a是什么类型? IntArray
var result=0
a.forEach {
result +=it
}
return result
}
异常处理
java异常:编译时异常、运行时异常.
java的编译时异常一定要处理,不然报错;Kotlin不检查编译时异常,Kotlin认为大部分的编译时异常都是没有必要的。
//运行时异常,java和Kotlin处理是一样的
var a=10
var b=0
//java.lang.ArithmeticException
try {
a/b
}catch (e:ArithmeticException){
}finally {
println("最终一定会执行")
}
递归
逻辑比较简单,容易实现;但是如果层级太深,容易栈内存溢出(内存开销比较大)。
/**
* 求n的阶乘
*/
fun fact(n:Int):Int{
if(n==1){
return 1
}else{
return n* fact(n-1)
}
}
/**
* 求第n个斐波那契数列
*/
fun fibonacci(n:Int):Int{
if(n==1 || n==2){
return 1
}else{
return fibonacci(n-2)+fibonacci(n-1)
}
}
尾递归:函数在调用自己之后没有执行其他任何的操作就是尾递归。
尾递归优化核心原理:将递归转为迭代。
尾递归优化步骤:
- 需要将递归转化为尾递归
- 加上tailrec
//递归
fun sum(n:Int):Int{
if(n==1){
return 1
}else{
return n+sum(n-1)
}
}
//尾递归
fun sum2(n:Int,result:Int=0):Int{
if(n==1){
return 1
}else{
return sum2(n-1,result+n)
}
}
//尾递归优化
tailrec fun sum3(n:Int,result:Int=0):Int{
if(n==1){
return 1
}else{
return sum3(n-1,result+n)
}
}
运算符
Kotlin中每一个运算符对应的都是一个方法,运算符相当于是方法的简写。
class Student{
var name:String="haha"
var age:Int=22
// operator fun plus(student:Student):Student{
// return this
// }
operator fun plus(student:Student):Int{
return this.age+student.age
}
}
val s1=Student()
val s2=Student()
//val newStudent=s1+s2
val newAge=s1+s2