Kotlin学习(三):Lambda编程

3.1 集合创建与遍历

3.1.1 List和Set集合

传统意义上,集合主要是List和Set,再广泛一点,还有Map这样的键值对数据结构。这些在Java中都是接口,List主要实现类是ArrayList和LinkedList,Set的主要实现类是HashSet,Map的主要实现类是HashMap。

现在需要创建一个包含许多水果名称的集合,在Java中:

var list = ArrayList<String>()
list.add("apple")
list.add("banana")
list.add("pear")

在Kotlin也可以这样做,但还有更简单的方法:

var list = listOf("apple","banana","pear")

需要注意的是,listOf()方法创建的是不可变的集合(元组),不可对集合进行添加、删除或修改操作

要创建可变的集合,需要使用mutablelistOf()方法

Set集合与List集合使用方法相近,但需注意Set集合底层使用hash映射机制存放数据,故集合元素不能保证有序

val list= mutableListOf("apple","banana","pear")//创建可变集合list
list.add("watermelon")
//set集合创建方法与list相近,使用setOf()和mutableSetOf()方法
val set= mutableSetOf("apple","banana","pear")//创建可变集合Set
//需要注意的是,Set集合底层使用hash映射机制存放数据,故集合元素不能保证有序

3.1.2 Map集合

Map是一种键值对形式的数据结构,传统Map用法是创建一个HashMap实例,再分别将键值对数据添加到Map中

val map=HashMap<String,Int>()//创建HashMap实例
map.put("apple",1)//用put方法添加键值对数据
map.put("banana",2)
map.put("pear",3)
val a=map.get("apple")//用get方法获取值

Kotlin中还有更简单的操作,这是一种类似数组下标的语法结构

val map=HashMap<String,Int>()//创建HashMap实例
map["apple"]=1//添加键值对数据
map["banana"]=2
val a=map["apple"]//获取值

Kotlin还提供了mapOf()和mutableMapOf()方法进一步简化了Map的用法

val map= mutableMapOf("apple" to 1,"banana" to 2,"pear" to 3)
for((fruit,num) in map) {//遍历键值对集合
        println("fruit is " + fruit + ", number is " + num)
}

3.2 集合的函数式API

3.2.1 maxBy()

对于需求:取得集合中名字最长的水果,我们有方法:

val list = listOf("apple","banana","pear")
var maxLengthFruit = ""
    for(fruit in list){
   	 if(fruit.length > maxLengthFruit.length){
    	maxLengthFruit=fruit;
	}
}
println("max length fruit is "+maxLengthFruit)

如果我们使用函数式API,还可以更简单:

 val list = listOf("apple","banana","pear")
 val maxLengthFruit=list.maxBy { it.length }
 println("max length fruit is "+maxLengthFruit)

正常情况下,我们只能向函数传入变量,但借助Lambda可以传入一小段代码(长度无限制,但不建议将过长的代码写入Lambda表达式,影响代码可读性)

Lambda表达式的语法结构为:{参数名1:参数类型,参数名2:参数类型 -> 函数体}

大部分情况下,我们只需要使用其结构的简化版本

接上例,maxBy()方法接受了一个Lambda类型的参数,并在遍历集合时将每次遍历的值作为参数传递给Lambda表达式

maxBy()的工作原理是根据传入的条件遍历集合,来找到该条件下的最大值

对上例的Lambda表达式展开:

 val list = listOf("apple","banana","pear")
//Lmabda表达式的完整形式
 val lambda = {fruit:String->fruit.length}
 val maxLengthFruit=list.maxBy(lambda)

我们再对展开的Lambda表达式进行简化:

val maxLengthFruit = list.maxBy({fruit:String -> fruit.length})//Lambda表达式可以作为参数直接传入函数
val maxLengthFruit = list.maxBy(){fruit:String -> fruit.length}//若Lambda参数是函数的最后一个参数时,可以将其放在括号外
val maxLengthFruit = list.maxBy{fruit:String -> fruit.length}//若Lambda参数是函数的唯一参数时,括号可省略
val maxLengthFruit = list.maxBy{fruit -> fruit.length}//Lambda表达式的参数列表在大多数情况下不需要声明参数类型
val maxLengthFruit = list.maxBy{it.length}//Lambda表达式的参数列表只有一个参数时,不必声明参数名,可用it关键字代替

3.2.2 map()

map()方法可以将集合内每个元素都映射成另外的值,映射规则在Lambda表达式中指定,并产生一个新的集合,

如对上例集合元素全部转为大写字母:

val list = listOf("apple","banana","pear")
val newList = list.map{it.toUpperCase()/*转为大写*/}//映射后得到新集合

3.2.3 filter()

filter()方法用于过滤集合中的数据,

如对上例建立新映射,只保留5个字母以内的水果:

val list = listOf("apple","banana","pear")
val newList = list.filter { it.length <= 5 /*过滤集合数据,只保留长度<=5的数据*/}.map{it.toUpperCase()/*转为大写*/}

注意,本例对集合先调用filter()方法,再调用map()方法,这样减少了映射转换的元素数量,提高了效率

3.2.4 any(),all()

any()方法用于判断集合中是否至少存在一个元素满足指定条件

all()方法用于判断集合中是否所有元素都满足指定条件

val list = listOf("apple","banana","pear")
val anyRes = list.any { it.length <= 5 }
val allRes = list.all { it.length <= 5 }
println("anyRes is "+anyRes)
println("allRes is "+allRes)

结果如下:

anyRes is true
allRes is false

3.3 Java函数式API的使用

JavaAPI中的Runnable接口,只要能实现该接口的Java方法,就可以使用函数式API

如Java的线程类Thread:

new Thread(new Runnable(){//使用匿名类提供实例化对象
    @override
    public void run(){
        System.out.println("Thread is running");
    }//我们创建了Runnable接口的匿名类实例,并将其传给Thread类的构造方法,
}).start();//最后调用Thread类的start()方法执行这个线程

如果用Kotlin实现这段代码:

Thread(object: Runnable{//Kotlin中舍弃了new关键字,因此创建匿名类时用到object
	override fun run(){
		println("Thread is running")
	}
}).start()

如果使用Java函数式API:

Thread(Runnable{//因为Runnable类只有一个方法需要实现,因此即使不显式重写run()方法,Kotlin也明白Runnable后面的Lambda表达式
    println("Thread is running")//是在run()方法中的内容
}).start()

当我们在使用Android SDK时,用到的许多函数也是Java语言编写,因此会经常用到Java函数式API

例如Android中常用的点击事件接口OnClickListener:

public interface OnClickListener{
    void onClick(View v);//可以看到,该接口只有一个方法需要实现
}

假设我们现在拥有一个按钮button实例,用Kotlin代码注册该按钮的点击事件:

button.setOnClickListener{
}

注意,Java函数式API的使用都限定于从Kotlin中调用Java方法,而且单抽象方法接口也必须是用Java语言设计的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BinBalll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值